typescript 方法对象中第一个参数的类型

lsmepo6l  于 2022-11-18  发布在  TypeScript
关注(0)|答案(2)|浏览(172)

我就喜欢这种类型

type d = {
  (e: 'edit', value: boolean): void;
  (e: 'download', value: boolean): void;
  (e: 'delete', value: boolean): void;
}

我想设置一个函数的类型,它只接受'edit' | 'download' | 'delete',即所有类型为d的e值。
例如:

function myFunc(e: ??what type??) {
}
myFunc('edit'); // valid type
myFunc('some') // invalid type
yc0p9oo0

yc0p9oo01#

请尝试改用Actions来建构回呼类型。

type Action = "edit" | "download" | "delete";
type Callback = (e: Action, value: boolean) => void;

现在,您可以指定类型

function myFunc(e: Action) { ... }
oaxa6hgo

oaxa6hgo2#

这里的问题是d是一个重载的函数类型。通常,你可以使用Parameters实用程序类型来轻松地获取函数的参数类型。但是Parameters只返回 last 重载的类型。
但是我们可以通过创建自己的支持N重载的实用程序类型来解决这个限制。

type OverloadedParameters<T> = 
    T extends { (...args: infer R1) : any; (...args: infer R2) : any; (...args: infer R3) : any ; (...args: infer R4) : any } ? [R1, R2, R3, R4] :
    T extends { (...args: infer R1) : any; (...args: infer R2) : any; (...args: infer R3) : any } ? [R1, R2, R3] :
    T extends { (...args: infer R1) : any; (...args: infer R2) : any } ? [R1, R2] :
    T extends (...args: infer R) => any ? [R] : any

OverloadedParameters最多接受4个重载。您可以根据需要将其扩展为任意多个重载。只需遵循以下模式即可。
现在我们得到一个包含重载函数d的所有参数类型的元组,剩下要做的就是用number索引它,得到所有参数的并集,然后用0索引它,得到每个并集元素的第一个元素。

function myFunc(e: OverloadedParameters<d>[number][0]) {}

myFunc('edit') // ok
myFunc('some') // Error

Playground

相关问题