-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeScript 高级类型及用法 #12
Comments
很赞 |
讲解得挺清晰的 |
强,讲得非常棒 |
总结得很棒 |
这里的 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
本文详细介绍了 TypeScript 高级类型的使用场景,对日常 TypeScript 的使用可以提供一些帮助。
前言
本文已收录在
Github
: https://github.com/beichensky/Blog 中,走过路过点个 Star 呗一、高级类型
交叉类型(&)
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。
语法:
T & U
用法:假设有两个接口:一个是
Ant
蚂蚁接口,一个是Fly
飞翔接口,现在有一只会飞的蚂蚁:联合类型(|)
联合类型与交叉类型很有关联,但是使用上却完全不同。
语法:
T | U
用法:假设声明一个数据,既可以是
string
类型,也可以是number
类型再看下面这个例子,
start
函数的参数类型既是Bird | Fish
,那么在start
函数中,想要直接调用的话,只能调用Bird
和Fish
都具备的方法,否则编译会报错二、关键字
类型约束(extends)
语法:
T extends K
可以在泛型中对传入的类型进行约束
也可以判断 T 是否可以赋值给 U,可以的话返回 T,否则返回 never
类型映射(in)
会遍历指定接口的 key 或者是遍历联合类型
类型谓词(is)
语法:
parameterName is Type
具体的应用场景可以跟着下面的代码思路进行使用:
看完联合类型的例子后,可能会考虑:如果想要在
start
函数中,根据情况去调用Bird
的fly
方法和Fish
的swim
方法,该如何操作呢?首先想到的可能是直接检查成员是否存在,然后进行调用:
但是这样做,判断以及调用的时候都要进行类型转换,未免有些麻烦,可能会想到写个工具函数判断下:
看起来简洁了一点,但是调用方法的时候,还是要进行类型转换才可以,否则还是会报错,那有什么好的办法,能让我们判断完类型之后,就可以直接调用方法,不用再进行类型转换呢?
OK,肯定是有的,类型谓词
is
就派上用场了每当使用一些变量调用
isFish
时,TypeScript
会将变量缩减为那个具体的类型,只要这个类型与变量的原始类型是兼容的。待推断类型(infer)
可以用
infer P
来标记一个泛型,表示这个泛型是一个待推断的类型,并且可以直接使用比如下面这个获取函数参数类型的例子:
判断 T 是否能赋值给
(param: infer P) => any
,并且将参数推断为泛型 P,如果可以赋值,则返回参数类型 P,否则返回传入的类型再来一个获取函数返回类型的例子:
判断 T 是否能赋值给
(param: any) => infer U
,并且将返回值类型推断为泛型 U,如果可以赋值,则返回返回值类型 P,否则返回传入的类型原始类型保护(typeof)
typeof v === "typename"
或typeof v !== "typename"
看下面这个例子,
print
函数会根据参数类型打印不同的结果,那如何判断参数是string
还是number
呢?有两种常用的判断方式:
根据是否包含
split
属性判断是string
类型,是否包含toFixed
方法判断是number
类型使用类型谓词
is
typeof
一展身手的时候了类型保护(instanceof)
与
typeof
类似,不过作用方式不同,instanceof
类型保护是通过构造函数来细化类型的一种方式。instanceof
的右侧要求是一个构造函数,TypeScript
将细化为:prototype
属性的类型,如果它的类型不为any
的话还是以 类型谓词 is 示例中的代码做演示:
最初代码:
使用
instanceof
后的代码:可以达到相同的效果
索引类型查询操作符(keyof)
keyof T
这里,
keyof Person
返回的类型和 'name' | 'age' 联合类型是一样,完全可以互相替换keyof
只能返回类型上已知的 公共属性名例如我们经常会获取对象的某个属性值,但是不确定是哪个属性,这个时候可以使用
extends
配合typeof
对属性名进行限制,限制传入的参数只能是对象的属性名索引访问操作符(T[K])
T[K]
三、映射类型
只读类型(
Readonly<T>
)只读数组(
ReadonlyArray<T>
)只能在数组初始化时为变量赋值,之后数组无法修改
可选类型(
Partial<T>
)用于将
T
类型的所有属性设置为可选状态,首先通过keyof T
,取出类型T
的所有属性,然后通过
in
操作符进行遍历,最后在属性后加上?
,将属性变为可选属性。必选类型(
Required<T>
)和
Partial
的作用相反用于将
T
类型的所有属性设置为必选状态,首先通过keyof T
,取出类型T
的所有属性,然后通过
in
操作符进行遍历,最后在属性后的?
前加上-
,将属性变为必选属性。提取属性(
Pick<T>
)Pick
来实现。排除属性(
Omit<T>
)定义:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
用法:比如长方体有长宽高,而正方体长宽高相等,所以只需要长就可以,那么此时就可以用
Omit
来生成正方体的类型摘取类型(
Extract<T, U>
)语法:
Extract<T, U>
定义:
type Extract<T, U> = T extends U ? T : never;
用法:
排除类型(
Exclude<T, U>
)语法:
Exclude<T, U>
定义:
type Exclude<T, U> = T extends U ? never : T
用法:
属性映射(
Record<K, T>
)Person
类型的数组转化成对象映射,可以使用Record
来指定映射对象的类型比如在传递参数时,希望参数是一个对象,但是不确定具体的类型,就可以使用
Record
作为参数类型不可为空类型(
NonNullable<T>
)type NonNullable<T> = T extends null | undefined ? never : T
构造函数参数类型(
ConstructorParameters<typeof T>
)实例类型(
InstanceType<T>
)函数参数类型(
Parameters<T>
)函数返回值类型(
ReturnType<T>
)四、总结
高级类型
关键字
number
、string
、boolean
、symbol
)prototype
属性类型T
对应属性 P 的类型映射类型
写在后面
如果有写的不对或不严谨的地方,欢迎大家能提出宝贵的意见,十分感谢。
如果喜欢或者有所帮助,欢迎 Star,对作者也是一种鼓励和支持
The text was updated successfully, but these errors were encountered: