从泛型类型推断泛型参数
Inferring generic parameters from generic types
我 运行 在尝试推断特定对象的泛型类型上的泛型参数时遇到了问题:
type Box <T extends object> = { value: T; }
function set <T extends object>(box: Box <T> , newValue: T): void {
box.value = newValue;
}
const bbox: Box <{ foo: string }> = {
value: {
foo: "bar"
}
};
set(bbox, {
foo: "baz"
}); // OK as expected
set(bbox, 42); // ERR as expected
set(bbox, {
bar: "baz"
}); // ERR as expected
set(bbox, {}); // OK, unexpected
set(bbox, { /* no autocomplete/intellisense is given here for valid props */ });
如果您提供 {}
作为参数,TypeScript 会将 {}
推断为函数的有效类型。这也意味着在编辑器中,指定对象类型的字段不会自动完成,因为 {}
匹配所有对象。
是否有关于 TypeScript 如何推断通用参数的顺序(即 newValue
的推断覆盖 Box<T>
的推断,并且任何对象都可以分配给 {}
)?如果是这样,有没有办法避免这种情况?
您可以通过添加一个额外的参数来部分解决这个问题:
function set <T, TN extends T> (box: Box <T> , newValue: TN): T {
box.value = newValue;
return newValue;
}
const bbox: Box <{ foo: string }> = {
value: {
foo: "bar"
}
};
set(bbox, {}); // ERR, expected
set(bbox, { /* still no autocomplete/intellisense */ });
但是,您仍然没有收到任何 autocomplete/IntelliSense。我猜这是因为 extends
,以及您不再直接寻找 T
的原因。
如果您这样声明 set
,您可以使 TypeScript 从第一个参数开始进行推理:
function set<T extends object, B extends Box<T>>(box: B, newValue: B['value']): void {
box.value = newValue;
}
不知道它是否解决了自动完成问题。
我对自动完成的工作原理知之甚少,无法确切地告诉您为什么它在您的情况下不起作用;我的直觉是它还没有完全致力于泛型类型推断。强制它提交推断类型的一种解决方法是将 set
更改为 curried function,如下所示:
const intelliSet = <B extends Box<{}>>(box: B) =>
(newValue: B['value']) => set(box, newValue);
intelliSet(bbox)( { foo: 'bar' }); // note the second function call
intelliSet(bbox)( { /* autocomplete works here */ });
我不知道是否有非变通的解决方案。如果尚不存在,我倾向于在 GitHub 上提交建议问题。 This one is possibly relevant, especially this comment。无论如何,祝你好运!
我 运行 在尝试推断特定对象的泛型类型上的泛型参数时遇到了问题:
type Box <T extends object> = { value: T; }
function set <T extends object>(box: Box <T> , newValue: T): void {
box.value = newValue;
}
const bbox: Box <{ foo: string }> = {
value: {
foo: "bar"
}
};
set(bbox, {
foo: "baz"
}); // OK as expected
set(bbox, 42); // ERR as expected
set(bbox, {
bar: "baz"
}); // ERR as expected
set(bbox, {}); // OK, unexpected
set(bbox, { /* no autocomplete/intellisense is given here for valid props */ });
如果您提供 {}
作为参数,TypeScript 会将 {}
推断为函数的有效类型。这也意味着在编辑器中,指定对象类型的字段不会自动完成,因为 {}
匹配所有对象。
是否有关于 TypeScript 如何推断通用参数的顺序(即 newValue
的推断覆盖 Box<T>
的推断,并且任何对象都可以分配给 {}
)?如果是这样,有没有办法避免这种情况?
您可以通过添加一个额外的参数来部分解决这个问题:
function set <T, TN extends T> (box: Box <T> , newValue: TN): T {
box.value = newValue;
return newValue;
}
const bbox: Box <{ foo: string }> = {
value: {
foo: "bar"
}
};
set(bbox, {}); // ERR, expected
set(bbox, { /* still no autocomplete/intellisense */ });
但是,您仍然没有收到任何 autocomplete/IntelliSense。我猜这是因为 extends
,以及您不再直接寻找 T
的原因。
如果您这样声明 set
,您可以使 TypeScript 从第一个参数开始进行推理:
function set<T extends object, B extends Box<T>>(box: B, newValue: B['value']): void {
box.value = newValue;
}
不知道它是否解决了自动完成问题。
我对自动完成的工作原理知之甚少,无法确切地告诉您为什么它在您的情况下不起作用;我的直觉是它还没有完全致力于泛型类型推断。强制它提交推断类型的一种解决方法是将 set
更改为 curried function,如下所示:
const intelliSet = <B extends Box<{}>>(box: B) =>
(newValue: B['value']) => set(box, newValue);
intelliSet(bbox)( { foo: 'bar' }); // note the second function call
intelliSet(bbox)( { /* autocomplete works here */ });
我不知道是否有非变通的解决方案。如果尚不存在,我倾向于在 GitHub 上提交建议问题。 This one is possibly relevant, especially this comment。无论如何,祝你好运!