浅谈类型
-----------部分内容摘抄自《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关键字声明类型,那么即只读的了。
type A = readonly string[]; // readonly string[] type B = ReadonlyArray<string>; // readonly string[] type C = Readonly<string[]>; // readonly string[] type D = readonly [number, string]; // readonly [number, string] type E = Readonly<[number, string]>; // readonly [number, string]
9. null、undefined、void和never
null 空对象、undefined 尚未赋值的变量、void 没有return返回语句、never 永不返回的函数,例如函数抛出异常,或者永远运行下去
10. 枚举
枚举的作用是列举类型中包含的各个值。这是一种无序数据结构,访问键时,TypeScript将检查指定的键是否存在。《TypeScript编程》一书的作者建议添加const关键字,并且显示赋值为字符串,以避免一些安全问题。
enum Language { English, // 0,如果没有显式赋值,那么默认是从0开始的阿拉伯数字 Spanish, // 1 Russian // 2 } const enum Color { Red = '#c10000', Blue = '#007ac1', Pink = 0xc10050, White = 255 }