推荐阅读
假设我们有一个 colors 对象:
type KnownKeys = 'red' | 'green' | 'blue' // and more...
const colors = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
// ...
}
// 显然,这里的值是 `string`
const red = colors.red
// 如果 key 来自后端接口,它既可能是已知的 KnownKeys,也可能是任意的 string
const colorKey = await fetch('/api/color')
// 显然,这里 colorValue 应当是 `string | undefined` 类型
const colorValue = colors[colorKey]
colors
定义为 Record<KnownKeys, string>
,因为这会导致 colors.unknownKey
跑错(key 不存在);colors
定义为 Record<string, string>
,因为这会导致 colors.unknownKey
的类型变为 string
;colors
定义为 Record<string, string | undefined>
,因为这会导致 colors.red
的类型变为 string | undefined
;这种情况,我们应该定义 colors
的类型为:
type KnownKeys = 'red' | 'green' | 'blue' // and more...
type Colors = Record<string, string | undefined> & {
[key in KnownKeys]: string
}
Colors['red'] // string
Colors['unknown-key'] // string | undefined
更一般地,我们可以定义一个通用类型:
type Obj<K extends string | number, V> = Record<string | number, V | undefined> & {
[key in K]: V
}
// 那么:
const colors: Obj<KnownKeys, string> = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
// ...
}
如非特别声明,本站作品均为原创,遵循【自由转载-保持署名-非商用-非衍生 创意共享 3.0 许可证】。
对于转载作品,如需二次转载,请遵循原作许可。