基于键大写的 TypeScript 类型
TypeScript types based on capitalization of a key
正在尝试向我正在使用的现有 JS 库添加类型。不幸的是,库有一个规则,即对象中值的类型在某种程度上是由其关联键的首字母大写决定的。我认为像下面这样的东西可能会起作用,但它不起作用。
type UppercaseLetters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
type LowercaseLetters = Lowercase<UppercaseLetters>;
type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`
// Define these types just so it compiles
type SomeRefType = number;
type SomePropType = boolean;
type Spec = {
type: string
} & {
[s in RefKey]: SomeRefType
} & {
[s in PropKey]: SomePropType
};
这样编译,但是Spec
变成的实际类型是:
type Spec = {
type: string;
} & {} & {}
有什么想法吗?也许这种情况对于 TypeScript 来说太过分了。
示例对象:
const specObj: Spec = {
type: 'Some string',
Apple: 3,
Orange: 6,
lowerCaseKey: false,
anotherOne: true
}
我删除了
type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`
并替换为 UppercaseLetters
和 LowercaseLetters
类型
是你要找的吗?
如Alateros
in the comments, since typescript@4.4
you can use index signatures for template literals所述。
尽管您仍然必须确保 type
字段必须是必需的,并且可能具有与 lowercased
键类型不兼容的类型。所以你可以这样写 Spec
类型:
type Spec = {
[K in RefKey | PropKey]: 'type' extends K
? string
: K extends RefKey
? SomeRefType
: K extends PropKey
? SomePropType
: never
} & {
type: string
}
正在尝试向我正在使用的现有 JS 库添加类型。不幸的是,库有一个规则,即对象中值的类型在某种程度上是由其关联键的首字母大写决定的。我认为像下面这样的东西可能会起作用,但它不起作用。
type UppercaseLetters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
type LowercaseLetters = Lowercase<UppercaseLetters>;
type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`
// Define these types just so it compiles
type SomeRefType = number;
type SomePropType = boolean;
type Spec = {
type: string
} & {
[s in RefKey]: SomeRefType
} & {
[s in PropKey]: SomePropType
};
这样编译,但是Spec
变成的实际类型是:
type Spec = {
type: string;
} & {} & {}
有什么想法吗?也许这种情况对于 TypeScript 来说太过分了。
示例对象:
const specObj: Spec = {
type: 'Some string',
Apple: 3,
Orange: 6,
lowerCaseKey: false,
anotherOne: true
}
我删除了
type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`
并替换为 UppercaseLetters
和 LowercaseLetters
类型
是你要找的吗?
如Alateros
in the comments, since typescript@4.4
you can use index signatures for template literals所述。
尽管您仍然必须确保 type
字段必须是必需的,并且可能具有与 lowercased
键类型不兼容的类型。所以你可以这样写 Spec
类型:
type Spec = {
[K in RefKey | PropKey]: 'type' extends K
? string
: K extends RefKey
? SomeRefType
: K extends PropKey
? SomePropType
: never
} & {
type: string
}