小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
序言:
这是搞定 TS 第四篇,如果没有基础的小伙伴想要从零搞定 TS ,请从第一篇开始juejin.cn/post/701033…
第一题
使用类型别名定义一个 EmptyObject 类型,使得该类型只允许空对象赋值
type EmptyObject = {}
// 测试用例
const shouldPass: EmptyObject = {}; // 可以正常赋值
const shouldFail: EmptyObject = { // 将出现编译错误
prop: "TS"
}
使用类型别名定义一个 takeSomeTypeOnly 函数的类型定义,让它的参数只允许严格SomeType类型的值。具体的使用示例如下所示
type SomeType = {
prop: string
}
// 更改以下函数的类型定义,让它的参数只允许严格SomeType类型的值
function takeSomeTypeOnly(x: SomeType) { return x }
// 测试用例:
const x = { prop: 'a' };
takeSomeTypeOnly(x) // 可以正常调用
const y = { prop: 'a', additionalProp: 'x' };
takeSomeTypeOnly(y) // 将出现编译错误
本题考查内容
never 的应用,如果一个类型被赋值为了never,那么它将不接受任何赋值,这样就起到了限制参数的作用。
题解 EmptyObject
type EmptyObject = {
// type PropertyKey = string | number | symbol
[K in PropertyKey]: never
}
// 测试用例
const shouldPass: EmptyObject = {}; // 可以正常赋值
const shouldFail: EmptyObject = { // 将出现编译错误
prop: "TS"
}
解题思路为,将该对象key值遍历,将所有属性赋值为never,属性为never类型意味着无法赋值,无法赋值也就没法拥有属性,有属性就有类型,有类型就不是never,所以就会报错。
题解 takeSomeTypeOnly
解题思路:
- SomeType类型的属性就不管,不是SomeType就把类型变为never
type SomeType = {
prop: string
}
type Exclusive<T1, T2 extends T1> = {
[K in keyof T2]: K extends keyof T1 ? T2[K] : never
}
// 更改以下函数的类型定义,让它的参数只允许严格SomeType类型的值
function takeSomeTypeOnly<T extends SomeType>(x: Exclusive<SomeType, T>) { return x }
// 测试用例:
const x = { prop: 'a' };
takeSomeTypeOnly(x) // 可以正常调用
const y = { prop: 'a', additionalProp: 'x' };
takeSomeTypeOnly(y) // 将出现编译错误
定义入参,将SomeType的通过,没包含的赋值为never将无法通过。
第二题
定义 NonEmptyArray 工具类型,用于确保数据非空数组。
type NonEmptyArray<T> = // 你的实现代码
const a: NonEmptyArray<string> = [] // 将出现编译错误
const b: NonEmptyArray<string> = ['Hello TS'] // 非空数据,正常使用
考察知识点
题解1
type NonEmptyArray<T> = [T, ...T[]]
将数组第一项定义为 T 类型,如果是空数组,第一项将为 undifind类型
题解2
type NonEmptyArray<T> = T[] & { 0: T };
利用交叉类型,交叉结果为索引 0 的那项类型为T,目的是和第一种结果一样