浅谈类型
-----------部分内容摘抄自《TypeScript编程》-----------------
1. any
代表不确定变量的值属于什么类型,声明它是任意类型,可以赋予任意类型的值,但这就意味着ts倒退回js了,不建议使用。如果不声明类型,默认也是any。
let testAny: any;
2. unknown
同any,代表不确定变量的值属于什么类型,声明它是unknown,可以赋予任意类型的值,但unknown比any多了一层限制,当调用变量上的方法时必须断言变量类型,否则编译器会提示错误,如果确定并非错误可以通过注释@ts-ignore告知编译器请忽略。
let testUnknown: unknown; (testUnknown as string).toString(); // @ts-ignore testUnknown.toString();
3. 原始值类型
boolean、number、string、symbol
4. 对象类型
当一个变量被声明为拥有某些属性的对象时,如果该变量被赋值不包含那些属性的对象,那么ts编译器将提示错误。一般情况下,直接用对象字面量初始化一个变量时,可以不用声明该变量类型,ts编译器会自动推断变量类型。
function testObjType(obj: {firstName: string, lastName: string}) {
console.log(obj.firstName, obj.lastName);
}
testObjType({firstName: 'john', lastName: 'barrowman'});
默认情况下,TypeScript对对象的属性要求十分严格。如果声明对象有个类型为number的属性b,TypeScript将预期对象有这么一个属性,而且只有这个属性。如果缺少b属性,或者多了其他属性,TypeScript将报错。当然,TypeScript支持声明可选属性。
/**
* 1) a有个类型为number的属性b
* 2)a可能有个类型为string的属性c。如果有属性c,其值可以为undefined
* 3)a有个类型为string的只读属性d
* 4)a可能有任意多个数字属性,其值为布尔值
* 5) a可能有任意多个字符串属性,其值为任意值
*/
let a: {
b: number,
c?: string,
readonly d: string,
[key: number]: boolean, // [属性名类型]: 属性值类型,key可以是其它字符串
[key2: string]: any
} = {
b: 123,
d: '456'
};
a.b = 666;
a.d = '789'; // Cannot assign to 'd' because it is a read-only property.ts(2540)
5. type声明类型别名
类型声明格式上与变量声明并初始化类似…此外,与let和const一样,类型别名采用块级作用域。每一块代码和一个函数都有自己的作用域,内部的类型别名将遮盖外部的类型别名。
type Age = number;
type Person = {
name: string,
age: Age
};
let age = 55;
let driver: Person = {
name: 'James May',
age: age
}
6. 类型间的且与或( & | )
type Cat = { name: string, purrs: boolean };
type Dog = { name: string, barks: boolean, wags: boolean };
type CatOrDogOrBoth = Cat | Dog;
type CatAndDog = Cat & Dog;
// Cat
let a: CatOrDogOrBoth = { name: 'Bonkers', purrs: true };
// Dog
a = { name: 'Domino', barks: true, wags: true };
// | Both
a = { name: 'Donkers', barks: true, purrs: true, wags: true };
// & Both
let b: CatAndDog = { name: 'Domino', barks: true, purrs: true, wags: true };
7. 数组
TypeScript支持两种注解数组类型的句法:T[] 和 Array<T>,如果没有显式声明类型,TypeScript编译器会根据初始化的值自动推断。
const arr = [1, 3, 4]; // number[],或者 Array<number>
8. 元组
元组是array的子类型,是定义数组的一种特殊方式,长度固定,各索引位上的值具有固定的已知类型。
let a: [number] = [1];
// [名,姓,出生年份] 形式的元组
let b: [string, string, number] = ['malcolm', 'gladwell', 1963];
b = ['queen', 'elizabeth', 'ii', 1926]; //Type 'string' is not assignable to type 'number'.
b = ['queen', 'elizabeth', 11, 1926]; //Type '[string, string, number, number]' is not assignable to type '[string, string, number]'.
// 元组类型 数组 -> 二维数组,数组中的每一个元素是一个元组
let trainFares: [number, number?][] = [
[3.75],
[8.25, 7.70],
[10.50]
];
// 上面那个二维数组等价于
let moreTrainFares: ([number] | [number, number])[] = [
// ...
]
// 字符串列表,至少有一个元素
let friends: [string, ...string[]] = ['Sara', 'Tali', 'Chloe', 'Claire'];
// 元素类型不同的列表
let list : [number, boolean, ...string[]] = [1, false, 'a', 'b', 'c'];
未使用readonly关键字声明类型的数组、元组是可以通过push,splice等方法修改数组的。如果使用了readonly关键字声明类型,那么即只读的了。