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)
所以我得到了这段代码,用于检查从多个 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)