如何在打字稿中显式定义具有不同元组类型的元组数组?

格诺·罗德纳

我正在编写一个转换器,该转换器使用查找对象将元组数组转换为对象,该对象告诉函数哪个字符串映射到哪些属性。但是,我找不到一种方法告诉打字稿它是具有特定类型的元组的数组,生成的元组始终是联合。看起来是这样的:

interface EndObj {
    a: number; 
    b: string;
    c?: number;
}
interface InitObj {
    d: string;
    e: string;
    f: string;
}

const map = {
    d: 'a',
    e: 'b',
    f: 'c'
} as const;

type MapType = typeof map;
type ResultTuple<T extends keyof InitObj> = [T, EndObj[MapType[T]]];
type ResultTupleArray = ResultTuple<keyof InitObj>[];

const resultObj: ResultTupleArray = [['d', 1], ['e', 3], ['f', 3]]; // invalid! the value of 'e' should only allow strings

我认为类型脚本允许这样做的原因是,因为ResultTupleArray是用定义的keyof InitObj,因此生成的元组数组泛型始终是相同的,因此T将始终是相同的,而不是每个数组条目都特定,因此只能用并集来描述。

这是我发现的方式:

const undetected: ResultTuple<keyof InitObj> = ['e', 4]; // should be invalid
const detected: ResultTuple<'e'> = ['e', 4]; // actually shows an error for 4 (Type 'number' is not assignable to type 'string'.)

对于上下文,这里是转换器的外观:

function mapInitToEnd(resultO: ResultTupleArray) {
    const endObj: EndObj = {
        a: -1,
        b: ''
    };

    for (const tuple of resultO) {
        const [key, val] = tuple;
        const mappedKey = map[key];
        endObj[mappedKey] = val;
    }
    return endObj;
}

有没有办法告诉打字稿,泛型仅对元组数组中的每个条目有效,而对整个数组无效?

卡兹

您希望分布ResultTuple定义,以便如果T是键的并集,则结果是元组的并集。在给定代码的情况下,完成此操作的最简单方法是使定义成为分布式条件类型,该条件类型免费提供以下行为:

type ResultTuple<T extends keyof InitObj> = T extends any ? [T, EndObj[MapType[T]]] : never;

类型参数为T extends U ? X : Ywhere时,将启动分布式条件类型T因此,要使此事情发生在上面,我们添加了否则没有用的T extends any ? ... : never检查。现在,您的代码将给您您期望的错误:

const resultObj: ResultTupleArray = [['d', 1], ['e', 3], ['f', 3]];  // error!
// number not assignable to string ----------> ~~~~~~~~

还有其他方法可以实现此行为。例如,通过构建映射类型并立即查找其属性:

type ResultTuple<T extends keyof InitObj> = { [K in T]: [K, EndObj[MapType[K]]] }[T];

两种方法都应该起作用。


好吧,希望能有所帮助;祝好运!

操场上的代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在打字稿中编写`Invert`类型以反转元组的顺序

如何在打字稿中添加自定义类型以扩展具有某些条件的基本类型

在打字稿中创建元组类型

如何在打字稿中定义对象类型的对象

如何在打字稿中定义嵌套字典类型

如何在打字稿中检查数组的类型

如何在打字稿中定义const数组

如何在打字稿中对具有条件的对象数组求和

有没有办法在打字稿中为具有唯一项的数组定义类型?

如何在打字稿类型定义中使用常量?

打字稿:从元组类型中删除条目

如何从具有键数组的对象中获取元组类型

在打字稿中,如何定义异步功能的类型

如何在打字稿元组中使用扩展运算符?

如何在打字稿中的forEach下定义类型?

如何在打字稿中定义观察者的类型

如何在打字稿2.0 / 3.0中添加自定义“类型”

您如何在打字稿中定义同时属于对象和函数的类型?

如何在打字稿配置中包括缺少的类型定义文件?

如何在打字稿中创建自定义数据类型?

如何在打字稿中为aa子类(React.Component)编写类型定义?

如何在打字稿中编写匿名函数的函数类型定义?

如何在打字稿中制作一种类型的函数链(数组)?

在打字稿中创建数组类型

如何在打字稿中获得“这个”类型

如何在打字稿中公开API返回的类型

如何在打字稿中向`... args`添加类型

如何在打字稿中强制变量的类型?

如何在打字稿中获取方法返回类型