我已经成功地为我的泛型 A 类型使用了一个默认值,这在将它用作对象参数(函数 c)时效果很好,但是如果我试图将它用作传入函数参数的返回类型(函数 d) 它不正确错误 Object literal may only specify known properties, and 'ping' does not exist in type 'B'.
type A = { foo: string }
type B = { bar: string }
function c<T = A, InferredType extends T = T>(config: InferredType): void { }
function d<T = A, InferredType extends T = T>(config: () => InferredType): void { }
c({ foo: 'foo' });
c({ bar: 'bar' }); // Correctly errors
c<A>({ bar: 'bar' }); // Correctly errors
c<B>({ bar: 'bar' });
c<B>({ bar: 'bar', ping: 'ping' }); // Correctly errors
d(() => ({ foo: 'foo' }));
d(() => ({ bar: 'bar' })); // Correctly errors
d<A>(() => ({ bar: 'bar' })); // Correctly errors
d<B>(() => ({ bar: 'bar' }));
d<B>(() => ({ bar: 'bar', ping: 'ping' })); // Should error with unknown property but doesn't
d<B>((): B => ({ bar: 'bar', ping: 'ping' })); // Errors correctly but requires duplicate type
如果我第二次指定类型 (B),正如您在最后一行看到的那样,它会按预期工作,但这违背了最初使用泛型的目的。
这是 typescript 本身的问题还是我在这里遗漏了什么?
最佳答案
我一直在调查您的问题,据我了解,它应该是这样工作的。
如果你查看你的 d()
函数的类型,你有一个 InferredType extends T
.
第 16-18 行,T
传递为 B
.当您尝试使用 T
被传递为 A
( d<A>(() => ({ bar: 'bar', ping: 'ping' }));
) 它会触发一个错误说 foo
是必需的。
所以我认为您的 InferredType 被解释为 { ping?: string}
因为它扩展了你的 T
类型。你可以继续,例如:d<B>(() => ({ bar: 'bar', ping: 'ping', pong: 'pong', hello: 'hello' }));
.只要bar
已定义,没有错误。
如果说的不够清楚,欢迎追问!
关于typescript - 默认泛型作为参数按预期工作,但不作为函数参数的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58846811/