gpt4 book ai didi

通用的 typescript 两层联合类型推断

转载 作者:行者123 更新时间:2023-12-04 08:00:21 25 4
gpt4 key购买 nike

我想通过 TypeScript 编写一种小型语言,并为其定义基本数据类型:

type BasicDataType = {
kind: 'text'
} | {
kind: 'number'
};
然后我定义了一个泛型类型来表达它的实例:
type BasicInstance<B extends BasicDataType> = B extends { kind: 'number' } ?
number
: B extends { kind: 'text' } ?
string
: never;

let a: BasicInstance<{ kind: 'number' }> = 1;
let b: BasicInstance<{ kind: 'text' }> = '';
它运行良好,但是当我尝试定义高级类型及其实例时:
type DataType = {
kind: 'single',
t: BasicDataType
} | {
kind: 'array',
t: BasicDataType,
};
type Instance<D extends DataType> = D extends { kind: 'single', t: infer B } ?
BasicInstance<B>
: D extends { kind: 'array', t: infer B } ?
Array<BasicInstance<B>>
: never;
我得到了错误:

error TS2344: Type 'B' does not satisfy the constraint 'BasicDataType'.Type 'B' is not assignable to type '{ kind: "number"; }'.


似乎 TypeScript 无法理解 B 必须是 BasicDataType。为什么会发生?我该如何解决?

最佳答案

推断的类型并不总是像您期望的那样精确。以这个类型定义为例:

type NotWorking<T extends {x: {y: number}}> =
T extends {x: infer N} ? N['y'] : never
它失败了 Type '"y"' cannot be used to index type 'N'. ,即使因为 T extends {x: {y: number}}约束, N['y']应该存在。要进行类型检查,您可以添加另一个条件 N extends {y: number} ,这将始终通过:
type Working<T extends {x: {y: number}}> =
T extends {x: infer N} ? N extends {y: number} ? N['y'] : never : never
对于您的类型,您可以输入 B extends BasicDataType外部的额外条件和使用 infer K对于那种你只需要一个 extends条件涵盖所有类型:
type Instance<D extends DataType> =
D extends { kind: infer K, t: infer B }
? B extends BasicDataType
? K extends 'single' ? BasicInstance<B>
: K extends 'array' ? Array<BasicInstance<B>>
: never
: never
: never
TypeScript playground

关于通用的 typescript 两层联合类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66508683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com