TypeScript Structural Comparison of Circular Tuples

jdg4fx2g  于 10个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(105)

TypeScript 版本: 3.8.2
搜索词: structure, resolve, compare, equality, type, mismatch, circular, tuple, cycle, recursive
代码

我试图在运行时表示一些类型信息。我定义了以下枚举:

  1. enum Type {
  2. Int = "Int",
  3. List = "List",
  4. }

然后我定义了一个 Codec 类型:一个元组,其中第一个元素是给定的 Type 枚举值,第二个元素(可选)是另一个 Codec:

  1. type Codec<
  2. T extends Type,
  3. C extends Codec<Type> | undefined = undefined
  4. > = C extends undefined ? [T] : [T, C];

我可以像预期的那样分配 Codec:

  1. const c1: Codec<Type.Int> = [Type.Int];
  2. const c2: Codec<Type.List, Codec<Type.Int>> = [Type.List, [Type.Int]];

我还为 Type.IntCodec 创建了辅助函数:

  1. type IntCodec = Codec<Type.Int>;
  2. const createIntCodec = (): IntCodec => [Type.Int];
  3. const intCodec = createIntCodec(); // signature is `[Type.Int]`

然而,我无法为嵌套其他 CodecCodec 创建辅助函数:

  1. type ListCodec<C extends Codec<Type>> = Codec<Type.List, C>;
  2. const createListCodec = <C extends Codec<Type>>(of: C): ListCodec<C> => [Type.List, of]; // error

这导致了一个错误:Type '[Type.List, C]' is not assignable to type 'Codec<Type.List, C>'. ts(2322)
Playground 链接
任何想法都将非常感谢!谢谢!

icomxhvb

icomxhvb1#

这可能是由 #35741 修复的。

rsaldnfx

rsaldnfx2#

weswigham,太棒了!

关于这个场景,我还想指出一件事:

  1. const sadCodec: Codec<
  2. Type.List,
  3. Codec<
  4. Type.List,
  5. Codec<Type.Int>
  6. >
  7. > = [Type.List, [Type.List, [Type.Int]]];

上述代码会产生错误:

  1. Type '[Type.List, [Type.Int]]' does not satisfy the constraint '[Type]'.
  2. Types of property 'length' are incompatible.
  3. Type '2' is not assignable to type '1'.

...尽管 Codec 类型具有1个或2个元数。希望这对解决方法有所帮助。&感谢你为4.0里程碑做出的贡献!

展开查看全部
slhcrj9b

slhcrj9b3#

我想要将这个问题转化为一个新的问题对。这个问题更容易被看作是约束传播失败的问题

  1. type Thing<A> = A extends string ? 1 : 2;
  2. function fn1<T extends string>(n: T): Thing<T> {
  3. // Should be OK
  4. return 1;
  5. }
  6. function fn2<T extends string>(n: T): Thing<T & string> {
  7. // Is OK... but this is a no-op? ^^^^^^^^
  8. return 1;
  9. }

这个例子写成这样...

  1. type Codec<
  2. T extends Type,
  3. C extends Codec<Type> | undefined = undefined
  4. > = C extends undefined ? [T] : [T, C];

...对我们来说更难分析,因为其正确行为取决于知道任何可以合法扩展 Codec<Type> 的东西都不可能扩展 undefined ,但这种反事实分析在大多数情况下很难做到百分之百准确,除非我们能够轻松地重写这些边缘情况。
我有一个本地分支来复制约束到受限制的示例化,但它在太复杂的项目中导致了新的类型约束循环错误,无法在合理的时间内进行分析。

展开查看全部

相关问题