TypeScript 入门 07 - 接口类型与类型别名

375 阅读2分钟

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)
    }
    
    // 不能使用接口已定义之外的变量,如 id
    

    readonly 是静态类型检测层面的只读,实际上并不能阻止对对象的篡改。

  • 定义函数类型

    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;
      }
      // 报错