提问人:nick zoum 提问时间:11/2/2023 最后编辑:nick zoum 更新时间:11/2/2023 访问量:58
Typescript 基于泛型修改类型
Typescript modify type based on generic
问:
问题
有没有办法让类型的泛型修改类型本身?
可以在不创建两个函数的情况下完成吗?
这与 js 功能无关,只是关于让类型匹配。
例
当我使用泛型调用函数时,我希望返回类型为 。
当我用它调用它时,应该是.
但是,当我用泛型调用它或不提供泛型时,它应该是 .HTMLInputElement
Array<HTMLInputElement>
HTMLSelectElement
Array<HTMLSelectElement>
never
string
缩小的示例,这不起作用,因为返回类型始终是(尽管 T 具有正确的值):Array<T> | string
type InteractiveElement = HTMLInputElement | HTMLSelectElement;
function getValue<T extends InteractiveElement = never>(): Array<T> | string {
return null as unknown as Array<T> | string; //
}
const inputValue = getValue<HTMLInputElement>(); // should be ChangeEvent<HTMLInputElement>
const selectValue = getValue<HTMLSelectElement>(); // should be ChangeEvent<HTMLSelectElement>
const emptyValue = getValue(); // should be string
答:
3赞
jcalz
11/2/2023
#1
您可以通过重载来执行此操作,以便首先使用非泛型调用签名:getValue()
function getValue(): string;
function getValue<T extends InteractiveElement>(): Array<T>;
function getValue() {
return null!
}
const inputValue = getValue<HTMLInputElement>(); // Array<HTMLInputElement>
const selectValue = getValue<HTMLSelectElement>(); // Array<HTMLSelectElement>
const emptyValue = getValue(); // string
或者,您可以让函数返回一个条件类型,该类型检查是否为(这要求条件类型不是分布式的,因此用 + 包装)并返回,如果是,或者如果不是:T
never
[
]
string
Array<T>
function getValue<T extends InteractiveElement = never>():
[T] extends [never] ? string : Array<T> {
return null!
}
const inputValue = getValue<HTMLInputElement>(); // Array<HTMLInputElement>
const selectValue = getValue<HTMLSelectElement>(); // Array<HTMLSelectElement>
const emptyValue = getValue(); // string
无论哪种方式,此示例都无法正确实现,因为 JavaScript 没有实际的函数参数可供操作。但既然你说它是“缩小”的,也许没关系。
评论
0赞
T.J. Crowder
11/2/2023
[T] extends [never]
——我必须试着记住这一点。:-)
0赞
nick zoum
11/2/2023
谢谢,这就是我一直在寻找的。我想我必须阅读一些关于条件类型的知识。
1赞
Silvan Bregy
11/2/2023
#2
除了上面的答案之外,这里还有一个使用 type 而不是 .它还使用条件类型,这似乎是这里最合适的方法。undefined
never
type InteractiveElement = HTMLInputElement | HTMLSelectElement;
type EventByValue<T> = T extends undefined ? string : ChangeEvent<T>
function getValue<T extends InteractiveElement | undefined = undefined>(): EventByValue<T> {
return null as any
}
const inputValue = getValue<HTMLInputElement>(); // ChangeEvent<HTMLInputElement>
const selectValue = getValue<HTMLSelectElement>(); // ChangeEvent<HTMLSelectElement>
const emptyValue = getValue(); // string
下一个:过载解决方法中的混淆
评论
ChangeEvent
change
Event
Array
Array