TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
在typescript中,我们定义对象的方式要用关键字interface(接口)
接口初探
interface LabelledValue {
label: string;
}
let myObj: LabelledValue = { label: "Size 10 Object" };
LabelledValue接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label属性且类型为string的对象。 需要注意的是,我们在这里并不能像在其它语言里一样,说传给 printLabel的对象实现了这个接口。我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。
还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
错误写法
我们在LabelledValue定义了label和b,但是对象里面缺少b属性,使用接口约束的时候不能多一个属性也不能少一个属性,必须与接口保持一致
interface LabelledValue {
label: string;
a: number
}
let myObj: LabelledValue = { label: "Size 10 Object" };
重名interface可以合并
interface A{
a:string
}
interface A{
b:number
}
var x:A={a:'zl',b:20}
接口可继承
interface A {
a: string
}
interface B extends A {
b: number
}
var x: B = { a: 'zl', b: 20 }
可选属性
使用?操作符,可选属性的含义是该属性可以不存在
interface SquareConfig {
color: string;
width?: number;
}
let obj: SquareConfig = {
color: 'red'
}
任意属性
使用[propName: string];propName可以换成别的,只是一个代号,比如[prop: string]
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
interface SquareConfig {
color: string;
width?: number;
[propName: string]: any
}
let obj: SquareConfig = {
color: 'red',
fontSize: '10px'
}
只读属性 readonly
一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性
interface Point {
readonly x: number;
y: number;
}
你可以通过赋值一个对象字面量来构造一个Point。 赋值后, x再也不能被改变了。
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
TypeScript具有ReadonlyArray<T>类型,它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
函数类型
接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。
一个参数,直接变量使用,实际定义了一个函数类型
interface Sum {
(a: number, b: number): number
}
let sum: Sum;
sum = function (a, b) {
return a + b;
}
两个参数,得用对象
interface Sum {
f: (a: number, b: number) => number,
a: string
}
let sum: Sum;
sum = {
a: '12',
f: (a, b) => a + b
}