如何在TypeScript中从字符串数组创建类型?

时间:2018-07-25 14:47:17

标签: typescript typescript2.0

基于字符串数组制作TypeScript类型的最佳方法是什么?我使用的是版本2.6.2。数组很长,我不想通过在Enum声明中复制字符串值来重复自己。

我想做的是这样的:

const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
export type Color = convertStringArrayToType(colors);

以下解决方案(source)可以正常工作,但感觉很笨拙:

/** Utility function to create a K:V from a list of strings */
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
  return o.reduce((res, key) => {
    res[key] = key;
    return res;
  }, Object.create(null));
}

/**
  * Sample create a string enum
  */

/** Create a K:V */
const Direction = strEnum([
  'North',
  'South',
  'East',
  'West'
])
/** Create a Type */
type Direction = keyof typeof Direction;

2 个答案:

答案 0 :(得分:12)

自打字稿3.4起,您可以使用as const并按如下所示从数组生成联合类型

const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'] as const;
export type Color = typeof colors[number]; // 'red'|'orange'|'yellow'|'green'|'blue'|'indigo'|'violet'

答案 1 :(得分:0)

以@guido-dizioli 的回答为基础,您可以创建一个可重用的函数来动态创建类型,并且仍然可以从 IntelliSense 中受益:

enter image description here 一个问题是调用者需要使用 as const:

定义数组
const properties = [
    "prepare", 
    "loadSession", 
    "proceedBasedOnSession", 
    "fetchConnection"
] as const;

function createObject<T extends readonly string[]>(steps: T): Record<T[number], object> {
    const typed = {} as Record<string, string>;
    steps.forEach(step => typed[step] = step);
    return typed as unknown as Record<T[number], object>;
}