TypeScript 隐式'any'在具有推断泛型类型的参数的方法中

f8rj6qna  于 6个月前  发布在  TypeScript
关注(0)|答案(6)|浏览(80)

隐式 'any' 方法参数推断出的泛型类型

版本与回归信息:

  • 我在尝试的每个版本中都遇到了这种行为,我查阅了关于类型推断的FAQ条目。

Playground链接:https://www.typescriptlang.org/play/?suppressImplicitAnyIndexErrors=true&ts=5.5.0-dev.20240531#code/C4TwDgpgBAwg9gOwM7AE4FcDGw6oDwAqAfFALxQDeAUFFAhAO5QAUAdOwIaoDmSAXHQgA3CKgDaAXQCUAggG4qAXwVUAlgmCiAZh0zQA4hHqpVmAApcOAWySES1WgCMuA5sFlSyJIXFUATBUUqKlBIKAAZVRRCKAgAD00EPyQoVAgOP0QAGxBKRUkScgcoMQBpKHUoAGsIEDgtKAIJATF4ZDQsHHwCMokiABooQ2NTC1RrWx7SvolAlT8ITCyuaC10BGxVRCgtODgY+MTk1PTMhBy8guYwSxsBSOixdlYmohkoH38VJY4kFIAxPaUGhQTQoZieChBII-P5QABCXDywQA9CioABJBBaURGPQ7DiqLJIKi7ODMMRUNEAPQA-CCxIC4IMKM5UG5IcFaIpFBJ+gzEagWWyOcCQTyJFRpKj0VicWkNtAGLgqiSyRSGUzhVxRcVaMBWGDgBCFNzeVKpMF1JpUDp8QA5dBWRyiMYTOzApwuFjuOhOl2oTykby+AJKYKhaAPYAAJgOCSMxzSGWyuShBTInpK5UqNTqDSaLTaKAw2FwhF6Aygjudrtuk0rsyU80WyzSO3Wm22ZLjBFiCaSKWTZwu6b613r9yisbwT3Yr3enzDVNl2NxiqgytQqtJexjGrRUDpmr22vZwE54t5-NoYkFZ91XKgEotQA

rjzwgtxy

rjzwgtxy1#

有趣的是,当你去掉T的约束时(TS playground),它仍然可以工作:

type Constructor<T> = {
  new (...args: never[]): T;
};

interface GenericParams<T> {
  bar: (t: T) => void;
}

type List<T> = {
  [K in keyof T]: [Constructor<T[K]>, GenericParams<T[K]>];
};

declare function foo<T>(params: List<T>): void;

class Foo {
  test() {}
}
class Bar {}

// both infer correctly here
foo([
  [Foo, { bar(t) {} }],
  [Bar, { bar(t) {} }],
]);

编辑://实际上,这里的问题是由扩展(可变元组)引起的(TS playground),只需将 List<[...T]> 替换为 List<T>

mkshixfv

mkshixfv2#

getContextualTypeForElementExpression 进入其"默认"分支(该分支中的最后一个),并调用 getElementTypeOfSliceOfTupleType 。可能应该在那里添加一个新的分支,并且它应该考虑到当可变元素 isGenericMappedType 看到它应该调用 substituteIndexedMappedType (在适当的情况下)。这应该与 getTypeOfPropertyOfContextualType 中相关分支的工作方式相似(也许甚至可以在这里重用该函数?)。这里还应该对其他形状的元组进行一些额外的考虑(具有多个可变元素、一些剩余元素、前导和尾随固定元素)

uqdfh47h

uqdfh47h3#

我昨天遇到了一个非常类似的错误。我只是想分享一下重现问题的步骤,以防它能帮助到其他人:

function mkAction<Input extends any[]>(action: {
    f1:(...xs:Input) => void,
    f2:(...xs:Input) => void,
}) {}

mkAction({
    f1(x:string, y:number) {},

    f2(x, y) {},
    // x and y are inferred as "any",
    // even though f2 is inferred as "(x: string, y: number) => void"
});
py49o6xq

py49o6xq4#

这是一个不同的问题。你能创建一个关于它的议题吗?关键是,注解参数不用于推断inferFromAnnotatedParameters中的剩余参数。

jjhzyzn0

jjhzyzn05#

我擅自将您的解释作为问题标题,因为这比我自己想出的好表达得多。

33qvvth1

33qvvth16#

有趣的是,当你去掉T的约束(TS playground)时,它仍然可以工作:

type Constructor<T> = {
  new (...args: never[]): T;
};

interface GenericParams<T> {
  bar: (t: T) => void;
}

type List<T> = {
  [K in keyof T]: [Constructor<T[K]>, GenericParams<T[K]>];
};

declare function foo<T>(params: List<T>): void;

class Foo {
  test() {}
}
class Bar {}

// both infer correctly here
foo([
  [Foo, { bar(t) {} }],
  [Bar, { bar(t) {} }],
]);

编辑://实际上,这里的问题是扩展(可变元组)(TS playground),只需将 List<[...T]> 替换为 List<T>
感谢建议;这个解决方法似乎已经解决了我正在工作的代码库中的推断问题。我想我应该把这个问题留开放,以便初始情况也可以得到修复?

相关问题