typescript - 默认泛型作为参数按预期工作,但不作为函数参数的返回类型

标签 typescript generics typescript-generics

我已经成功地为我的泛型 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

Playground Link

如果我第二次指定类型 (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/

相关文章:

javascript - 如何使用 typescript 检查对象内部的键和值

javascript - typescript 错误 "Cannot find name"

generics - 具有混合成员类型的通用 TypeScript 接口(interface)

java - 具有泛型类型的 Guava 函数

swift - swift 泛型函数中的类型可以由返回值决定吗?

typescript - 为什么 Typescript 箭头函数泛型与命名函数泛型的工作方式不同

typescript - 递归构建 typescript 类型

javascript - 如何检查我的复选框列表是否已选中或未选中 AngularJS 2

typescript - 数组索引字符串或数字的类型?

generics - 根据rust函数中的泛型选择常量