浅谈类型

-----------部分内容摘抄自《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
}
posted @ 2023-05-11 21:51  黄燃  阅读(18)  评论(0编辑  收藏  举报