Reputation: 1282
Trying to add types to an existing JS library I'm using. The library unfortunately has a rule that the type of the value in an object is somewhat determined by the capitalization of the first letter of its associated key. I thought something like the below might work, but it does not.
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
};
This compiles, but the actual type that Spec
becomes is:
type Spec = {
type: string;
} & {} & {}
Any ideas out there? Perhaps this case is just too out of the left field for TypeScript to handle.
Example object:
const specObj: Spec = {
type: 'Some string',
Apple: 3,
Orange: 6,
lowerCaseKey: false,
anotherOne: true
}
Upvotes: 2
Views: 1669
Reputation: 8340
As noted by Alateros
in the comments, since [email protected]
you can use index signatures for template literals.
Though you still have to ensure type
field must be required and may have the type that is not compatible with lowercased
keys type. So you may write Spec
type like that:
type Spec = {
[K in RefKey | PropKey]: 'type' extends K
? string
: K extends RefKey
? SomeRefType
: K extends PropKey
? SomePropType
: never
} & {
type: string
}
Upvotes: 1
Reputation:
I removed
type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`
and replaced with UppercaseLetters
and LowercaseLetters
types
Is it what are you looking for?
Upvotes: 0