Home > front end >  How do I use a string generic (not something iterable) to define a certain key in an object in TypeS
How do I use a string generic (not something iterable) to define a certain key in an object in TypeS

Time:01-22

I am trying to create a type of an object/interface in which certain key names can be modified by a generic. There are already tons of questions and answers about using generics to define keys iteratively as with [key: T] or [Key in T], but what I'm trying to do is different.

Let's say I have a simple type like this:

type Animal = {
    features: {
        hasTail: boolean,
        color: string,
    },
    maxAge: number,
    habitat: string,
};

Now what if I wanted to change the name of the key hasTail based on a few different possible options based on a non-iterable string type passed in through a generic. Ideally, I would like to be able to do something like this. (Forgive my ridiculous examples made from poor knowledge of animal classification).

type Animal<T extends "laysEggs" | "hasTail"> {
    features: {
        [T]: boolean,
        color: string,
    },
    maxAge: number,
    habitat: string,
}

This way I could define similar types by saying

type Reptile = Animal<"hasTail">;
type Mammal = Animal<"laysEggs">;

Or I could determine which type of animal a given piece of data was by going

function checkAnimal(a: Animal) {
    if ("hasTail" in a.features) {
        // now I know it's a Mammal
    ...

I'm trying to simplify things by giving these ridiculous animal examples, but I have a much more complicated use case that would benefit greatly for this kind of modification through generics.

However, as far as I can see, generics seem to only be used to pass iterable objects to provide a number of keys for a given object? I want to be able to provide a specific name for a specific single key in an object. Any ideas?

CodePudding user response:

So does this work for you?

type Animal<T extends "laysEggs" | "hasTail"> = {
    features: {
        [K in T]: boolean;
    },
    maxAge: number,
    habitat: string,
} & {
  features:{
    color: string;
  }
}
  •  Tags:  
  • Related