Frank Weindel
Frank Weindel

Reputation: 1282

TypeScript types based on capitalization of a key

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

Answers (2)

aleksxor
aleksxor

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
}

playground link

Upvotes: 1

user9760669
user9760669

Reputation:

I removed

type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`

and replaced with UppercaseLetters and LowercaseLetters types

enter image description here

Is it what are you looking for?

Upvotes: 0

Related Questions