07 - 接口类型与类型别名
让TS拥有描述复杂结构的能力。
Interface 接口类型
-
通过接口类型,可以清晰地定义模块内、跨模块、跨项目代码的通信规则。
-
"鸭子类型" | "结构化类型": 只要两个对象的结构一致,属性和方法的类型一致,则它们的类型就是一致的。
-
对比解构语法与内联接口类型混用
// JS 解构语法 function getInfo({name, age}){ // ... } // TS 解构与内联类型混用 function getInfo({name, age}: {name: string, age: ()=>number}){ // ... } // JS 解构语法, 定义别名 function getName({name: aliasName}){ // ... } // TS function getName(language: {name: string}){ console.log(language.name) }尽量使用interface接口,不要混淆两者
-
-
定义接口
interface PageLanguage { readonly name: string; // 只读属性 age?: ()=> number; // 可缺省属性 } function getName(language: PageLanguage){ console.log(language.name) } // 不能使用接口已定义之外的变量,如 idreadonly 是静态类型检测层面的只读,实际上并不能阻止对对象的篡改。
-
定义函数类型
interface Study { (language: PageLanguage): void } let study: Sduty = language => console.log('language')使用内联类型或类型别名定义函数类型
type Study = (language: PageLanguage) => void -
索引签名
inferface StringMap { [prop: string]: number; age: number; // ok name: string; // 错误:name属性的string类型不能赋值给字符串索引类型number } -
接口继承 extends
interface TsLanguage extends DyLanguage { rank: number; // 定义新属性 name: 'TypeScript'; // 用原属性类型(string) 的兼容的类型,重新定义属性 }同名的属性名定义会覆盖继承来的属性名定义。如果与原属性类型不兼容,会报错。
-
类接口实现接口
class LanguageClass implements ProgramLanguage { // ... } -
定义类型别名
type LanguageType = { name: string; age: () => number; }"type 类型别名 = 类型定义"
-
针对接口类型无法覆盖的场景,只能使用类型别名来接受
{ // 联合类型 type MixedType = string | number; // 交叉类型 type IntersectionType = {id: number; name: string} & {age: number; name: string} // 提取接口属性类型 type AgeType = ProgramLanguage['age'] } -
重复定义的类型,其属性会叠加
interface God { name: string; } interface God { id: number; } // 叠加为 interface God { name: string; id: number; }重复定义类型别名,会报错。
type Ts = { name: string; } type Ts = { id: number; } // 报错
-