【问题标题】:Inferring generic parameters from generic types从泛型类型推断泛型参数
【发布时间】:2017-09-18 04:05:36
【问题描述】:

我在尝试推断泛型类型的泛型参数时遇到了问题:

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&lt;T&gt; 的推断,并且任何对象都可以分配给{})?如果是这样,有没有办法避免这种情况?


你可以通过添加一个额外的参数来部分解决这个问题:

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 */ });

但是,您仍然没有收到任何自动完成/智能感知。我猜这是因为extends,以及您不再直接寻找T

【问题讨论】:

    标签: typescript generic-type-parameters


    【解决方案1】:

    我对自动完成功能的工作原理了解不多,无法确切告诉您为什么它在您的情况下不起作用;我的直觉是它还没有完全致力于泛型类型推断。强制它提交到推断类型的一种解决方法是将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 可能是相关的,尤其是this comment。无论如何,祝你好运!

    【讨论】:

      【解决方案2】:

      如果您像这样声明 set,则可以让 TypeScript 从第一个参数开始进行推理:

      function set<T extends object, B extends Box<T>>(box: B, newValue: B['value']): void {
          box.value = newValue;
      }
      

      不知道它是否解决了自动完成问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        • 1970-01-01
        • 1970-01-01
        • 2020-03-11
        • 1970-01-01
        相关资源
        最近更新 更多