首页 > 解决方案 > 打字稿减去文字数字类型

问题描述

TLDR:

就像是:

type type4= 5-1 //type 4
// also ok
type type4= '5'-'1' // type '4'

我怎样才能实现类似的目标?

细节

我想构建一个通用函数类型,它接收数字文字(或字符串文字)并返回数字的联合,直到'0'. 例如,如果'3'通过了,那么返回将是'0'|'1'|'2'. 让我们称之为泛型RangeUnion

type Union01 = RangeUnion<'1'> // should be '0'|'1'  - RangeUnion should be implemented

为什么?

这仅供参考,无需理解即可回答我的具体问题。如果您对上述问题没有答案,也许您可​​以为不同的实施提供一些想法。

我正在为反应组件构建开发人员 API,并且我想使用打字稿创建复杂的类型推断。无需过多介绍:当数组中的每个项目都依赖于数组中的先前项目时,我有类型数组。我想创建类型的交集,直到数组中的给定类型,例如:

// utilities
type GetIndex<A extends any[], T> = {
  [K in keyof A]: A[K] extends T ? K : never;
}[number];
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;

// actual
type Arr = [{ type0: any }, { type1: any }, { type2: any },]
type Type1 = GetIndex<Arr, { type1: any }> // type is '1' - good
type Union01 = RangeUnion<Type1> // should be 0|1 - RangeUnion should be implemented
type DesiredType = UnionToIntersection<Arr[Union01]> //type is { type0: any } & { type1: any }

操场

标签: typescript

解决方案


非常感谢@robert 和@captain-yossarian,您的回答帮助编写了我需要的完整解决方案,我做了一些细微的修改:

// utils
type GetIndex<Arr extends Array<any>, T> = Arr extends [...infer Tail, infer Last]
  ? Last extends T
    ? Tail["length"]
    : GetIndex<Tail, T>
  : never;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type BuildTuple<L extends number, T extends any[] = []> = T extends { length: L } ? T : BuildTuple<L, [...T, any]>;
type RangeUnion<N extends number, Result extends Array<unknown> = []> = Result["length"] extends N
  ? Result[number]
  : RangeUnion<N, [...Result, Result["length"]]>;

// actual
type Arr = [{ type0: any }, { type1: any }, { type2: any }];
type Type2 = GetIndex<Arr, { type2: any }>; 
type Union01 = RangeUnion<Type2>; 
type DesiredType = UnionToIntersection<Arr[Union01]>; //type is { type0: any } & { type1: any }
// works!

任何需要在打字稿中明确使用文字数字类型的加法或减法的人都可以在@Roberto Zvjerković 评论的精彩文章中看到它


推荐阅读