TypeScript | 青训营笔记

81 阅读3分钟

这是我参与第五届青训营伴学笔记创作活动的第一天

TypeScript

TypeScript是JavaScript的超集,扩展了JavaScript,并且由动态类型语言变为静态类型语言,为JavaScript添加了类型校验、推断等功能,增强可读性和可维护性。

image.png

TS的变量声明

编写TypeScript的变量可以给其声明类型,格式为变量名: 类型,例如

let a: number = 1;

对于有很多属性的对象,可以定义接口,声明对象时的类型为接口的名字。

interface IObject {
    name: string,
    school?: string,
    [key: string]: any
}

const obj: IObject = {
    name: 'Siji',
    age: 21
}

其中,可以用[key: string]: 类型的形式表示其他任意属性可以为什么类型的属性,问号表示该属性可空。类似地,可以用[key: number]: 类型表示数组。

TS泛型

当不确定变量具体的类型的时候,可以用泛型来表示。例如

// 接口泛型
interface Obj<T, U> {
    name: T,
    id: U
}

// 类型别名泛型
type TypeArr<T> = Array<T>

当函数需要用到泛型时,需要写在参数括号的前面。

// 函数泛型
type fun = <T>(agr1: T) => T[]

function fun1<T>(): T[] {
    return Array<T>();
}

当然,泛型也可以被约束或者拥有默认的类型

// 泛型约束
type IGetRepeatStringArr = <T extends string>(target: T) => T[]
const getStrArr: IGetRepeatStringArr = target => new Array(100).fill(target)
console.log(getStrArr(123))

// 泛型默认参数类型
type IGetRepeatStringArrDefault = <T = number>(target: T) => T[]
const getStrArr2: IGetRepeatStringArrDefault = (target) => new Array(100).fill(target)
const arr2 = getStrArr2('123')
console.log(arr2)

第一段代码中T的类型被约束为string,而参数为number,报错。
第二段代码中,默认的参数为number,但是传入字符串不会报错,并且得到的结果为字符串数组。

TS高级类型

联合类型和交叉类型

联合类型表示这一组类型中其中一个类型,例如 A | B | C 中,只会是其中一个类型。 交叉类型表示将多种类型叠加成为一种新的类型,如A & B & C,新的类型中有A、B、C中的所有属性。

image.png

上图表示一个书的对象数组,每本书有相同的属性,也有不同的属性,不同属性的书可以归为不同的类。但是为每种书都写一个接口或者类型别名,会多写很多遍重复的属性,这时可以用联合类型区别不同的属性,用交叉类型将相同的属性与不同种类书的属性合并。

Record

Record的定义为Record<key type, value type>,泛型的参数为键和值的类型。
Record的源码,:

image.png 其中,P是ts中的类型parameter。
[P in K]就是遍历里面的数据,每个值的类型都为T。
如果T的类型为any,当K的类型为string,可以表示为对象,当K的类型为number,可以表示为数组。

Partial

Partial的作用是生成一个新类型,这个类型的属性和T一样,但是全部都是可选属性。
源码:

image.png 其中,keyof相当于类似a|b|c,为联合类型的一种。

infer的使用

infer只能在在条件类型的extends子句中使用,类似于三目运算符,判断两个类型的其中一个。
例子:

image.png 类型IReturnType根据前面的条件,为R或者any。
更多infer的用法:TS进阶之infer - 简书 (jianshu.com)

总结

TypeScript为JavaScript提供了类型安全等功能,同时也增加了使用的难度,想写好高级的类型组合并且容易。

标题:TypeScript 高级数据类型 - 掘金

网址:juejin.cn/course/byte…