typescript 函数定义-一道3层TypeScript笔试题,你能答对多少层?

const func = () => {}

参数和返回值的类型都是链表,但具体类型未知typescript 函数定义,可以写unknown[]。

因此这两种函数类型的定义如下所示:

还有通过函数直接声明函数类型和通过接口声明函数类型后添加到变量类型中的两种类型。

由于具体元素类型未知typescript 函数定义,因此使用unknown。

在这里你可能会问any和unknown之间的区别:

any 和unknown 都可以接受任何类型:

然而,any 也可以参数化为任何类型,但unknown 不能。

typescript 函数定义_定义函数的规则_定义函数使用的关键字是

这仅用于接收其他类型,因此unknown比any更合适、更安全。

这层也是比较基础的ts句型,第三层比较难:

使用类型编程来实现精确的类型提示。 例如,如果参数传入[1,2,3],[4,5,6],那么返回值的类型应该提示出[[1,4],[2,5],[ 3,6]]

这里返回值类型要求精确,我们需要根据参数的类型动态生成返回值类型。

就是这样:

声明两个类型参数Target和Source,约束为unknown[],即元素类型的任意字段类型。

这两个类型参数就是传入的两个参数的类型。

返回值由 Zip 估计。

然后实现Zip的中间类型:

传入的类型参数是两个字段类型,我们还需要从中提取每个元素并将它们合并在一起。

提取元素可以使用模式匹配的方法:

所以类型可以这样定义:

type Zip<One extends unknown[], Other extends unknown[]> =
    One extends [infer OneFirst,...infer Rest1]
      ? Other extends [infer OtherFirst, ...infer Rest2]
        ? [[OneFirst, OtherFirst], ...Zip]
        : []
      : [];

分别提取两个字段的第一个元素,构造一个新的字段。 之后,递归处理剩余字段,直到字段为空。

这样就实现了我们想要的中间类型:

但如果将其作为返回值添加到函数中,就会报错:

因为声明函数时不知道参数是什么,自然无法估计Zip的值,所以这里就会出现类型不匹配的情况:

那么该怎么办?

typescript 函数定义_定义函数的规则_定义函数使用的关键字是

可以通过函数重载来解决:

ts支持函数重载,可以写多个同名函数的类型定义,最后写函数的实现,这样在使用这个函数时,就会根据参数的类型来匹配函数类型。

我们用类型编程的那种函数来写这些方法,是不会报错的。

让我们使用以下内容来看看:

为什么返回值类型不对?

虽然此时匹配的函数类型是正确的,但只是导入的类型不是文字类型。

这时候就可以加一个asconst了。

但是,添加 asconst 将推入 readonly[1,2,3]

定义函数的规则_定义函数使用的关键字是_typescript 函数定义

此类型不匹配,因此将 readonly 添加到类型参数的声明中:

但 Zip 函数的类型再次不匹配。

我们是否必须在所有使用此类型的地方添加 readonly ?

不行,我们不能删除只读修改吗?

Typescript 有一个外部中间类型只读:

索引类型的每个索引都可以用readonly来修改:

但是没有中间类型去掉readonly修饰,我们可以自己实现:

定义函数使用的关键字是_typescript 函数定义_定义函数的规则

用映射类型的句型构造一个新的索引类型,并添加-readonly,去掉readonly修饰的意义。

有的朋友可能会问,链表类型也是索引类型吗?

是的,索引类型是聚合多个元素的类型,所以对象、数组、类都是。

所以我们在链表上使用也是可以的:

(准确的说是元组,元组是一个元素数量固定的链表)

那么我们只需要在传入 Zip 之前使用 Mutable 去除 readonly 即可:

再试一次:

你完成了! 返回值的类型现在是正确的。

但仍然存在一个问题。 如果不直接传入字面值,则无法推断字面值的类型。 这个时候其实是错误的: