typescript - 具有泛型的类型别名表现出与非泛型类型不同的行为

标签 typescript generics metaprogramming

考虑以下代码:

type TestTuple = [
    { test: "foo" },
    {
        test: "bar";
        other: 1;
    }
];

type Foo<Prop extends string> = TestTuple extends Record<Prop, string>[]
    ? true
    : false;
type X = Foo<"test">;

type Prop = "test";
type Y = TestTuple extends Record<Prop, string>[]
    ? true
    : false;

// X is type false
const x: X = false;
// Y is type true
const y: Y = true;
Playground link .
类型 FooY完全相同,除了 Foo有一个通用参数 Prop , 而 Y只使用一个名为 Prop 的类型别名(不需要类型别名,Y 可以只是 TestTuple extends Record<"test", string>[] ? true : false 但我想让它们的声明完全相同)。所以,Foo<"test"> (别名为 X 类型)和 Y应该有相同的类型吧?显然不是。 X如类型 falseY是类型 true .更改 other房产在TestTuple到字符串或完全删除该属性会导致 XY是真的,这是预期的行为。
所以,我的问题是:这是为什么?这是编译器中的错误吗?如果是这样,是否已经提交了我无法找到的问题?或者,这是在 typescript 中处理泛型的某种奇怪方式吗?

最佳答案

更新 :这已为 TypeScript 4.2 修复:Playground link to code

我已提交 microsoft/TypeScript#41613关于这一点,在简化为以下最小示例之后:

type What<K extends string> =
    { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;

type Huh = What<"y">; // expect true but got false!
TypeScript 首席架构师 Anders Hejlsbergcommented :

When determining whether to defer resolution of the conditional type we relate the "most permissive instantiations" of the check and extends types. The constraint of the most permissive instantiation of the extends type ends up being { x: { [index: string]: 0 } }, but really it should be { x: { } }. It's a simple fix and I'll include it in this PR.


所以希望它最终会在 a new PR 中得到修复并可能被 TypeScript 4.2 合并到 TypeScript 中。 (更新:它已被合并。)如果是这样,我希望这应该解决您的问题中的问题,而不是用 {x: ...} 包装索引类型。 ,我们用元组类型包装它。
在此之前,您应该考虑使用类似 @Temoncher's answer 中的解决方法。 .
Playground link to code

关于typescript - 具有泛型的类型别名表现出与非泛型类型不同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64922800/

相关文章:

c# - 泛型类型仅在java中属于类类型

java - Java中的通用集合和通配符

c++ - 如何使用作为模板参数的模板

javascript - 如何在 NodeJS 中公开 TypeScript 模块?

java - Jersey 2.5 : Replacement for JResponse?

javascript - 从接口(interface)导出枚举

ruby - 为什么 eval 将方法创建为私有(private)方法?

ruby-on-rails - 标记要在模块中使用的特定 Rails 模型的最佳方法

Angular5,组件之间的交互

javascript - Angular 过滤阵列