函数类型
接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
interface SearchFunc { (source: string, subString: string): boolean; }
对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 比如,我们使用下面的代码重写上面的例子:
let mySearch: SearchFunc; mySearch = function(src: string, sub: string): boolean { let result = src.search(sub); return result > -1; }
可索引的类型
与使用接口描述函数类型差不多,我们也可以描述那些能够“通过索引得到”的类型,比如a[10]
或ageMap["daniel"]
。 可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。 让我们看一个例子:
interface StringArray { [index: number]: string; } let myArray: StringArray; myArray = ["Bob", "Fred"]; let myStr: string = myArray[0];
上面例子里,我们定义了StringArray
接口,它具有索引签名。 这个索引签名表示了当用 number
去索引StringArray
时会得到string
类型的返回值。
TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number
来索引时,JavaScript会将它转换成string
然后再去索引对象。 也就是说用 100
(一个number
)去索引等同于使用"100"
(一个string
)去索引,因此两者需要保持一致。
class Animal { name: string; } class Dog extends Animal { breed: string; } // 错误:使用数值型的字符串索引,有时会得到完全不同的Animal! interface NotOkay { [x: number]: Animal; [x: string]: Dog; }
字符串索引签名能够很好的描述dictionary
模式,并且它们也会确保所有属性与其返回值类型相匹配。 因为字符串索引声明了 obj.property
和obj["property"]
两种形式都可以。 下面的例子里, name
的类型与字符串索引类型不匹配,所以类型检查器给出一个错误提示:
interface NumberDictionary { [index: string]: number; length: number; // 可以,length是number类型 name: string // 错误,`name`的类型与索引类型返回值的类型不匹配 }