接口
四大属性
常规属性、可选属性、任意属性、只读属性
接口示例
interface Person {
readonly id: number; // 只读属性,只能在创建对象时赋值且不可改
name: string;
age?: number; // 可选属性,创建对象时可写可不写
// 任意属性,可添加任意属性,接口其他属性必须是该属性类型的子集,如将any改为string,
// 将会报错,因为age、id类型不是string类型的子集。
[propName: string]: any;
}
数组
数组的几种定义方式
let fibonacci: number[] = [1, 1, 2, 3, 5];
let fibonacci2: (number | string)[] = [1, '1', 2, 3, '5'];
let fibonacci3: Array<number> = [1, 1, 2, 3, 5]; // 数组泛型
interface NumberArray {
[index: number]: number;
}
let fibonacci4: NumberArray = [1, 1, 2, 3, 5]; // 用接口表示数组
let list: any[] = ['string', 20, {name: 'xxx'}]; // any类型数组
类数组
不能直接用 类型[] 来定义,通常有定义好的接口,如IArguments, NodeList, HTMLCollection
function sum() {
let args: IArguments = arguments;
}
函数
定义方式
声明式和表达式:
function sum(x: number, y: number) : number {
return x + y;
}
let mySum: (x: number, y: number) => number = function sum(x: number, y: number) {
return x + y;
}
// (x: number, y: number) => number
// 并不是ES6的箭头函数,左边是输入参数,右边是返回值类型
使用interface给变量一个函数形状
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== 1;
}
参数
可选参数
function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}
剩余参数
function push(array: any[], ...items: any[]) {
items.forEach(item => {
array.push(item);
})
}
重载
TypeScript会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
function reserve(x: number): number;
function reserve(x: string): string;
function reserve(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
断言
两种语法:<类型>值、值 as 类型(tsx中只能用这种)
function getLength(something: string | number): number {
if ((<string>something).length) {
return (<string>something).length;
} else {
return something.toString().length;
}
}
断言不是类型转换,不能断言不存在的联合类型。