数组
TS数组有两种写法:
第一种是形如let arr:number[];的形式;第二种是形如let arr:Array<number>;的形式。
一般地,数组中所有成员的类型相同,如果数组成员比较复杂,则可以使用联合类型let arr:Array<number|string>;相较于c/c++的数组,TS的数组成员数量可以动态变化,不会对数组边界进行检查,越界访问数组并不会报错。
TS数组的类型推断在初始化为空数组时自动更新,若一开始声明为number类型/被类型推断为number,却push入一个string元素,则会报错。
TS存在可读数组,可读数组方法比数组少,因此在继承的角度上可读数组是数组的父类,可读数组可以这样声明:
const arr:readonly number[] = [0, 1];,但是不能和数组的泛型写法一起使用,而是应该写作const a:ReadonlyArray<number> = [0, 1];
或const a:Readonly<number[]> = [0, 1];或const arr = [0, 1] as const;。
二维数组的写法为var arr:number[][] = [[1,2,3], [3,4,5]];
元组
元组是JS没有而TS特有的数据类型(不是说别的语言也没有的意思),元组的各个成员类型可以不同,因此声明时需要明确出来。如: const arr:[number,string,boolean]=[1,'a',true];
因为需要声明每个成员的类型,所以元组的成员数量是有限的,不像数组那么自由。但是存在可选成员,即在声明时在类型后面加上问号,这些可选成员需要放在所有必选成员后面,在数组中可以写或不写。
如果想要表示不限成员数量的元组,要使用扩展运算符。像下面的代码这样:
type NamedNums = [
string,
...number[]
];
const a:NamedNums = ['A', 1, 2,3,4,5];
扩展运算符可以用在元组的任意位置。
元组也有只读元组,写法为type t=readonly [number,string]或type t=Readonly<[number,string]>。
与数组相同,只读元组是元组的父类型。元组可以替代只读元组,而只读元组不能替代元组。
如果不采用扩展运算符,TS能够推断出成员数量。如果使用了扩展运算符使得元组的数量无法推断,TS会把元组当成数组处理。在一些指定了参数的方法中,为了传入成员数量不确定的数组,就需要把他写成成员数量确定的元组,再使用扩展运算符。
symbol类型
每个从 Symbol() 返回的 symbol 值都是唯一的。通过Symbol()函数生成,
生成返回的值属于unique symbol类型。unique symbol类型是symbol的子类,表示具体的symbol值。const命令为变量赋值 Symbol 值时,变量类型默认就是unique symbol,即const x=Symbol()//x:unique symbol,不过虽然都是symbol返回的值,类型却不能相等,即用===会报错。
unique symbol 类型可以用来做属性名,这样不会和其他属性名冲突。 Symbol 值做属性名时,它的类型只能是 unique symbol,不能是 symbol,会报错。也可以作为类的属性值,但只能赋给类的readonly static属性。
symbol的类型推断,let声明的symbol值推断为symbol类,而const声明的symbol值推断为unique symbol类。
函数
在声明函数时,需要声明参数类型和返回值类型。写法如下
function foo(a:number,b:boolean):boolean{
if(a==1&&b==true)
return true;
}
一般参数类型需要声明,如果TS无法判断参数类型,会推断参数的类型为any。返回值通常可以不写,TS会根据return进行推断。
函数赋值给变量的声明有两种写法:
const foo = function (a:string) {
console.log(a);
}
const foo:(a:string) => void =function(a) {
console.log(a);
}
这样写如果参数种类多显然十分麻烦,可以用type定义一个别名,简化代码,如:
type foo = (a:string,b:number,c:boolean) => void;
const aaa:foo = function (a,b,c) {
console.log('a',b,c);
};
TS允许传入的参数比实际声明的参数少。
TS箭头函数的写法为:
(arg): type => void
箭头后面跟着的是函数体内的内容。
返回值
void
一般来说,返回值为void等同于return undifined。但特别的,当变量、对象方法、函数参数的类型是 void 类型的函数时,可以接受返回任意值的函数。
type voidFunc = () => void;
const f:voidFunc = () => {
return 123;
};
但是返回值不能被调用,一旦被调用,仍会报错。
never
函数的返回值为never时,主要有两种情况。
(1)抛出错误函数。
function fail(msg:string):never {
throw new Error(msg);
}
(2)无限执行的函数。
const sing = function():never {
while (true) {
console.log('sing');
}
};
局部类型
函数内部允许用type声明其他类型,该类型只在函数内部有效,称为局部类型。
函数重载
函数同名,参数类型不同称为函数重载。TS的函数重载可以使用联合类型替代。