搞定TS,就靠这个系列(四)

664 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

序言:

这是搞定 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

解题思路:

  1. 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,目的是和第一种结果一样 ​