TypeScript 当将函数的类型参数传递给Map类型时,未检查类型约束,

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

Bug报告

🔎 搜索词

从函数传递时丢失的Map类型、泛型类型约束

🕗 版本与回归信息

  • 我尝试了每个版本,并查阅了关于泛型的常见问题解答条目

⏯ Playground链接

包含相关代码的Playground链接

💻 代码

type SomeMappedType<T extends Record<string, any>> = {
  [K in keyof T]: T[K]
}

function myFunc<T extends SomeMappedType<T>>(myArg: T){

}

const y: SomeMappedType<object> = {foo: 'bar'}; // okay.  makes sense.

//@ts-expect-error
const x: SomeMappedType<string> = {foo: 'bar'}; // This error makes sense. `string` type parameter violates the Record<string, any> constraint

myFunc<string>('hey');  // Why is `string` not checked against the `Record<string, any>` constraint in this context ??

🙁 实际行为

当我将 string 作为类型参数传递给 myFunc(即 myFunc<string>)时,没有出现错误。

🙂 预期行为

当我尝试进行以下函数调用时:myFunc<string>('hey');Typescript会报错并警告我 string 不满足 Record<string, any> 的约束条件。

c90pui9n

c90pui9n1#

在通话过程中,我们使用了一个特殊类型示例化 SomeMappedType<T> ,我们称之为 * ,这使得我们可以验证 T ,尽管它出现在递归位置。这个类型应该产生一个可以从示例化的 T 分配的类型,但没有其他类型,然而由于 SomeMappedType 是同态的,如果一个原始类型(字符串)进入,那么相同的原始类型(字符串)也会出来,所以实际上即使 string 不是 Record<string, any> ,这也能成功。

虽然不清楚如何解决这个问题,但欢迎任何人尝试。

jv2fixgn

jv2fixgn2#

@RyanCavanaugh 非常感谢你的回复!我明白了,这很有道理。我想知道是否可行,至少只是显示一个编译器警告,解释在这个上下文中的类型约束将没有任何效果?

2w2cym1i

2w2cym1i3#

我认为没有什么东西能清晰地区分有问题的案例和无问题的案例。这种行为已经存在了很长时间,但没有人注意到,所以我不认为我们会警告这个代码 - 它显然是一个边缘情况。

r1zhe5dt

r1zhe5dt4#

这实际上成功了,尽管 string 不是一个 Record<string, any>
我本来会猜相反的(即 string一个有效的示例化),原因和 string 可以分配给 {} 相同。

xxslljrj

xxslljrj5#

{} 不需要索引签名,但是 Record<string, any> 需要一个索引签名(?)

type A = string extends Record<string, any> ? true : false;
o8x7eapl

o8x7eapl6#

被诅咒了?
永远不要说TS团队没有幽默感。😄

相关问题