我不明白为什么泛型函数会自动获取泛型类型,而不向其提供任何内容。
type T<G = Record<string, any>> = {
id: keyof G
label: string
somethingElse?: string
}
此函数返回一个具有特殊属性的对象,如果未将属性传递给该对象,则id
该对象应该具有类型。如果通过,返回的应该是类型"random"
source
source
id
source
const element = <ID extends string = 'random'>({ source }: { source?: ID } = {}) =>
({
id: (source || 'random') as ID,
label: 'Element1',
}) as const satisfies T
// I don't want the return type to be "T", I want what it returns to satisfy "T".
// as you see I dont provide "somethingElse" key here, so I don't want it in the return type
type Data = { a: string; b: number }
这给出了我想要的确切错误,但前提是我使用变量:
const el1 = element() // el1 gets type { readonly id: "random"; readonly label: "Element1"; }
const el2 = element({source: 'b'}) // el2 gets type { readonly id: "b"; readonly label: "Element1"; }
const el3 = element({source: 'else'}) // el3 gets type { readonly id: "else"; readonly label: "Element1"; }
const b: T<Data>[] = [el, el2, el3] // el1 and el3 invalid, el2 valid. It is all correct
但为什么当我直接使用它而不使用变量时,它是有效的?它应该抛出一个错误
const a: T<Data>[] = [element()]
// No generic or property is provided to it "element()",
// why the return type of "element()" is { readonly id: keyof Data; readonly label: "Element1"; } ??
TypeScript 可以使用函数返回类型作为推理目标,这意味着泛型函数可以通过其返回的上下文类型以及其参数的已知类型来推断其类型参数。在
编译器期望
[element()]
是类型T<Data>[]
,因此element()
是类型T<Data>
,因此ID
是类型keyof Data
,并且没有错误。如果您不喜欢这样并且希望返回类型不用作推理站点,则可以使用实用程序类型来
NoInfer
阻止从该位置进行推理:如果
ID
没有从返回类型推断出,这应该没有效果,并且所有其他示例都是相同的:但现在您在最后一个示例中得到了所需的错误,因为
T<Data>
上下文不影响ID
. 由于ID
现在根本没有推理站点,因此它回退到默认值"random"
:Playground 代码链接