gpt4 book ai didi

Typescript 自动泛型类型,无需显式声明类型

转载 作者:行者123 更新时间:2023-12-04 07:55:00 24 4
gpt4 key购买 nike

如果我有一个具有两个功能的界面。一个函数返回一个值。我想在同一接口(interface)的另一个函数中使用值的类型。我确实使用了泛型,但每次创建新对象时都必须显式声明类型。但没有它也可以做到。例如:

interface MyObject<T> {
create(): T
update(value: T): void // use value type defined in create method
}
在这里我们使用上面的接口(interface)定义新对象:
let test: MyObject<string> = {
create() {
return "Hello"
},
update(value) {
// do something with value
},
}
可以写 MyObject没有 <string> .因为值类型已在 create 中定义方法?

最佳答案

您希望编译器推断 string对于泛型类型参数 T .唯一这样的地方generic type parameter inference发生在您调用泛型函数时,因此如果您想要这种行为,您需要从类型注释( const test: MyObject<string> = ... )重构为调用辅助函数( const test = toMyObject(...) )。
TS4.7+ 更新:
看起来像 microsoft/TypeScript#48358将与 TypeScript 4.7 一起发布,此时编译器确实能够根据从先前定义的属性推断的类型参数来上下文类型方法参数。届时,以下将起作用:

const toMyObject = <T,>(o: MyObject<T>) => o;

let test = toMyObject({
create() {
return "Hello"
},
update(value) {
value.toUpperCase()
},
})
请注意,这取决于对象文字成员的顺序,所以因为您需要 Tcreate() 推断在您可以在 update() 中使用它之前, 你需要 create()早于 update()在对象中。所以以下中断:
let test2 = toMyObject({
update(value) {
value.toUpperCase() // error
},
create() {
return "Hello"
},
});
Playground link for TS4.7+

TS4.6-的先前答案:
此外,您希望编译器推断 value 的类型。 update的回调参数方法。这种类型的推理称为 contextual typing .
不幸的是,当两者都依赖于同一个对象时,回调参数的上下文类型推断和泛型类型参数推断不能很好地配合使用。这是 TypeScript 的设计限制。见 microsoft/TypeScript#38872了解更多信息。
为了获得上下文类型推断和泛型类型参数推断,您的辅助函数需要将输入对象分成两部分:一个用于 create这样泛型类型参数 T可以推断,另一个为 update使回调参数 value的类型可以推断。
这给了我们这个:
const toMyObject = <T,>(
create: () => T,
update: (value: T) => void
): MyObject<T> => ({ create, update });

让我们测试一下:
let test = toMyObject(
() => { return "Hello" },
(value) => { console.log(value.toUpperCase()); }
);
// let test: MyObject<string>
看起来挺好的。编译器推断 testMyObject<string> 类型根据需要,以及回调参数 value也被推断为 string (正如您可以在 value.toUpperCase() 模式下调用 --strict 而不会出错的事实所证明的那样)。
Playground link to code for TS4.6-

关于Typescript 自动泛型类型,无需显式声明类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66747117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com