基本介绍

TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。

在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义约束。

(function (){
	// 描述一个对象的类型
	type myType = {
		name: string,
		age: number
	};
	const obj: myType = {
		name: 'sss',
		age: 111
	}
	/*
	*	接口用来定义一个类的结构
	*/
	interface myType2 = {
		name: string,
		age: number
	};
	const obj: myType2 = {
		name: 'www',
		age: 222
	}
})

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label);	// "Size 10 Object"
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);
分析:
1. printLabel() 有一个参数,并要求这个对象参数有一个名为`label` 类型为`string`的属性
2. 我们传入的对象参数实际上会包含很多属性(比如:size),但是编译器只会检查那些必需的属性(label)是否存在,并且其类型是否匹配
3. 类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以
interface LabelledValue {
	label: string;
}
function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
分析:
1. `LabelledValue` 接口就好比一个名字,用来描述示例 1 里的要求
2. 它代表了有一个 `label`属性且类型为`string`的对象
3. 只要传入的对象满足`LabelledValue`的必要条件,那么它就是被允许的

可选属性(?:)

接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在

interface SquareConfig {
    color?: string;
    width?: number;
  }

  function createSquare(config: SquareConfig) {
    let newSquare = {color: "white", area: 33};
    if (config.color) {
      newSquare.color = config.color;
    }
    if (config.width) {
      newSquare.area = config.width * config.width;
    }
    return newSquare;
  }

  let mySquare = createSquare({color: "black"});
  let mySquare2 = createSquare({color: "red", width: 10});
  // let mySquare3 = createSquare({color: "black", width: 10, height: 10}); // 报错:SquareConfig不存在height属性
  console.log(mySquare)	// {color: 'black', area: 33}
  console.log(mySquare2)// {color: 'red', area: 100}

只读属性(readonly)

interface Point {
  readonly x: number;
  readonly y: number;
}