定义Typescript字符串类型,以逗号分隔的并集类型?

时间:2019-12-24 17:40:18

标签: typescript

如何创建Typescript字符串类型,其中包括联合类型 AND 中的值,并用逗号分隔?

我认为这不存在,但是无论如何我都在问...

type AcceptableVal = 'cool' | 'wow' | 'biz' | 'sweet' | 'yowza' | 'fantastic';
type Amaze = // how do you define this?;

const dabes: Amaze = 'cool,wow';
const fancy: Amaze = 'biz,wow,fantastic';
const hachiMachi: Amaze = 'yowza,biz,sweet';

4 个答案:

答案 0 :(得分:2)

你不能。

Typescript可以键入string,可以包含任何内容,也可以键入确切的字符串,例如"cool""wow"。但是打字稿永远不会知道字符串是否包含某些字符。

完成这项工作的唯一方法是将它们存储为数组:

type AmazeArray = AcceptableVal[];
const dabes: AmazeArray = ['cool', 'wow'];

答案 1 :(得分:0)

听起来更像是要查看数组中是否有值。

const l: string[] = ['cool', 'wow', 'biz', 'sweet', 'yowza', 'fantastic'];
let r: string[] = l.filter(s  => s === 'cool');
if (r.length > 0) { console.log('Got one')}

您也可以拥有Enums

答案 2 :(得分:0)

使用ts4.1的新模板字符串功能,您可以使用以下实用程序来实现

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
    ? I
    : never;
type UnionToOvlds<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;

type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;

type UnionConcat<U extends string, Sep extends string> = PopUnion<U> extends infer SELF
    ? SELF extends string
        ? Exclude<U, SELF> extends never
            ? SELF
            :
                  | `${UnionConcat<Exclude<U, SELF>, Sep>}${Sep}${SELF}`
                  | UnionConcat<Exclude<U, SELF>, Sep>
                  | SELF
        : never
    : never;

答案 3 :(得分:0)

你可以用 template literal types.

type GoodDog = 'ruger' | 'kim' | 'abbie' | 'bo' | 'jasper';

type DogList = `${ GoodDog }` | 
               `${ GoodDog },${ GoodDog }` | 
               `${ GoodDog },${ GoodDog },${ GoodDog }`;

const favoriteDogs1: DogList = 'kim,abbie,ruger'

这将支持最多 3 个狗列表,并允许重复。您可以根据需要添加更多。

不幸的是,如果您尝试进行递归,则不允许这样做。我认为从理论上讲,可以使用“尾部条件”创建一种递归类型,但我无法立即弄清楚。

更好的方法可能是在数组(不是类型)上使用 as const

 const Colors = ['red', 'blue', 'green', 'orange'] as const;

这是一个运行时变量数组,因此您可以将其显示在您的 UI 中 - 将其添加到下拉列表等中。

然后你需要提取这个常量数组的“类型”(这只是因为我们把它做成了常量)。

type ExtractArrayType<T> = T extends ReadonlyArray<infer U> ? U : never;

type ColorType = ExtractArrayType<typeof Colors>;

这会给我们:

ColorType = 'red' | 'blue' | 'green' | 'orange;

请注意,如果我们没有用 as const 定义原始数组,那么 ColorType 将只是 string

我们现在可以使用这个类型并创建一个数组;

const colorList: ColorType[] = ['red', 'blue'];

这种方法对于大多数运行时情况更有用,尽管有时定义类似 red,blue 的内容并检查该类型会很好。