TypeScript 条件类型和 typeof

TypeScript Conditional Types and typeof

所以我得到了这段代码,用于检查从多个 string 常量构建 AnyOfTheAbove type

const IT_COULD_BE_THIS = 'something';
const OR_THAT = 'something else';
const OR_EVEN = 'the other thing';

export type AnyOfTheAbove =
    | typeof IT_COULD_BE_THIS 
    | typeof OR_THAT 
    | typeof OR_EVEN;

我很想写

export type AnyOfTheAbove = GetTypeof<
    | IT_COULD_BE_THIS 
    | OR_THAT 
    | OR_EVEN
>;

或类似。我有一种感觉,我可以用条件类型来完成这个。但到目前为止,我所有的尝试都付诸东流。这可行吗?

不可能,因为类型不接受前面没有 typeof 的运行时对象。 (类 和枚举除外)

如果真的不为每个对象typeof,你可以将所有对象包装在一个函数调用,然后提取类型一次使用typeof:

使用假函数

// No value produced at runtime, but infers union type statically
function unionType<T>(...arr: T[]): T { return null as unknown as T }

const IT_COULD_BE_THIS = 'something'
const OR_THAT = 'something else'
const OR_EVEN = 'the other thing'

// Extract types from function call
type AnyOfTheAbove = typeof AnyOfTheAbove
const AnyOfTheAbove = unionType(
  IT_COULD_BE_THIS,
  OR_THAT,
  OR_EVEN
)

这意味着运行时调用(只会 return null),但允许解决该限制。

使用元组

// You need to specify `string` to infer each string correctly:
// https://github.com/Microsoft/TypeScript/issues/26158
function tuple<T extends string[]>(...t: T) { return t }

const IT_COULD_BE_THIS = 'something'
const OR_THAT = 'something else'
const OR_EVEN = 'the other thing'

// Extract types from function call
type AnyOfTheAbove = typeof AllOfTheAbove[number]
const AllOfTheAbove = tuple(
    IT_COULD_BE_THIS,
    OR_THAT,
    OR_EVEN
)

事实上,这两种解决方案都使用了 Tuple,但其中一种意味着伪造的运行时调用,因为另一种只会将您的数组包装在函数调用中以正确推断类型。

None确实节省了字符,也没有简化可读性。


编辑 26/08/2019

使用枚举

如果您可以在一个枚举中定义所有这些字符串,您可以:

enum AllEnum {
  IT_COULD_BE_THIS,
  OR_THAT,
  OR_EVEN,
}

// Static type
type All = keyof typeof AllEnum

// Access all strings at runtime
const allAtRuntime = Object.keys(AllEnum)