接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
语法如下:
interface interface_name {
}
注意:接口不能转换为 JavaScript。 它只是 TypeScript 的一部分。(编译后就没有接口部分的js代码了)
例:
interface IPerson{
name: string,
age: number,
sayHi: () => string
}
let person: IPerson = {
name: 'Linda',
age: 18,
sayHi() {
return 'hello world';
}
};
联合类型和接口:
例.
interface RunOpts {
programe: string,
commandLine: string | string[] | (() => string)
}
let opts:RunOpts = {programe: 'test', commandLine: 'test1'};
console.log(opts.commandLine);
opts = {programe: 'test2', commandLine: ['t1', 't2']};
console.log(opts.commandLine);
opts = {programe: 'test3', commandLine: () => { return 'fn'}};
console.log(opts.commandLine());
接口和数组:
interface IArr {
[index: number]: boolean
}
let arr: IArr = [false, false, true, false];
只读属性:
interface Point{
readonly x: number,
readonly y:number
}
var point: Point = { x: 10, y: 20 };
point.x = 5; //error
只读数组 ReadonlyArray<T>
var arr: ReadonlyArray<number> = [1, 2, 3, 4];
arr[0] = 10; //error
readonly vs const
最简单判断该用readonly
还是const
的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const
,若做为属性则使用readonly
。
额外的类型检查
如果一个变量(或者函数参数)的类型是一个接口,但有些属性未在接口中声明就会报错
interface Test{
name: string,
age: number
}
var t:Test = {
name: 'xiaoming',
age: 10,
grade: 'A' //错误!!,因为在接口中未声明此属性
}
如何解决呢?
1. 类型断言
interface Test{
name: string,
age: number
}
var t: Test = {
name: 'xiaoming',
age: 10,
grade: 'A' //错误!!,因为在接口中未声明此属性
} as Test;
2. 如果能够确定对象中具有某些作为特殊用途的额外属性,可以使用 [propName:string]: 数据类型 (ps:propName 是随意起的,也可以叫别的名字)
interface Test{
name: string,
age: number,
[propName:string]: any
}
var t: Test = {
name: 'xiaoming',
age: 10,
grade: 'A' //错误!!,因为在接口中未声明此属性
};
3. 将值赋一个变量
interface Test{
name: string,
age: number,
[propName:string]: any
}
var t2 = {
name: 'xiaoming',
age: 10,
grade: 'A'
};
var t: Test = t2;
函数类型:
用接口来声明函数
interface searchFunc {
(source:string, sub:number):boolean
//参数:第一个参数是string类型,第二个参数是number类型
//返回值:boolean类型
}
使用时,函数的参数名称可以与接口中定义的一致,但是类型顺序要一致,可以在函数的参数中声明类型,也可以不声明
比如:
interface searchFunc {
(source:string, subString:string):boolean
}
var mySearch: searchFunc;
mySearch = function (src:string, sub:string):boolean {
let res = src.search(sub);
return res !== -1;
}
或者:
interface searchFunc {
(source:string, subString:string):boolean
}
var mySearch: searchFunc;
mySearch = function (src, sub) {
let res = src.search(sub);
return res !== -1;
}
可索引的类型:
eg.
interface StringArray{
[index: number]: string,
input: string
}
var arr: StringArray = { 0: '0', 1: '1', 2: '2', input: 'test' };
//通过 数字去索引得到的是一个字符串
TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number
来索引时,JavaScript会将它转换成string
然后再去索引对象。
interface NumberDictionary{
[propName: string]: number,
name: string, //不可以,因为上面已经声明了了 以字符串为索引,得到的数据类型为number
length: number
}
接口继承:
接口继承就是说接口可以通过其他接口来扩展自己。
Typescript 允许接口继承多个接口。
继承使用关键字 extends。
单接口继承语法:
Child_interface_name extends super_interface_name
多接口继承语法(继承的各个接口使用逗号 , 分隔):
Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name
单继承:例
let drumer = <Musician>{};
drumer.age = 10;
drumer.name = 'test';
drumer.instrument = 'piano';
console.log('drumer', drumer);
多继承:例
interface IParent1 {
v1: string
}
interface IParent2 {
v2: number
}
interface Child extends IParent1, IParent2{
v3: boolean
}
let version = <Child>{};
version.v1 = 'aa';
version.v2 = 1;
version.v3 = true;
//各种写法
interface Counter {
(start: number):string;//方法-->参数为start 返回值是string
// [index: number]: any; //数组
interval: number;
count: string | number | (() => string);
reset(): void;
sayHi: () => string;
sayWhat() : string;
increase();
}