我设法对类型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),如您在最后一行看到的那样,它会按预期工作,但是这违背了首先使用泛型的目的。
这是打字稿本身的问题,还是我在这里遗漏了什么?
答案 0 :(得分:3)
我一直在调查您的问题,据我所知,它应该可以那样工作。
如果查看您的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
,就不会出错。
不要犹豫,问是否不够清楚!