Home > Enterprise >  How to use generics with the value of a type definition in TypeScript?
How to use generics with the value of a type definition in TypeScript?

Time:05-09

I have some classes which all have a property called data. I have a type definition for the data type mapping which I'd like to use in the generics definition. So this is my code:

type DataTypes = {
  age: number;
  firstName: string;
  lastName: string;
};

abstract class AbstractBase<T extends DataTypes> {
  data: T;
}

class AgeComponent extends AbstractBase<DataTypes.age> {}

class FirstNameComponent extends AbstractBase<DataTypes.firstName> {}

class LastNameComponent extends AbstractBase<DataTypes.lastName> {}

So when using abstract class AbstractBase<T extends DataTypes> I'd like to tell TypeScript to accept the types according to the mappings in the type DataTypes.

Is this possible with TypeScript?

CodePudding user response:

You can pass to AbstractBase the key from DataTypes you want to use, and the use index access types to get the type from DataTypes:


abstract class AbstractBase<T extends keyof DataTypes> {
  data!: DataTypes[T];
}

class AgeComponent extends AbstractBase<"age"> {}

Playground Link

Or you can pass the type of the property directly:

abstract class AbstractBase<T extends DataTypes[keyof DataTypes]> {
  data!: T;
}

class AgeComponent extends AbstractBase<DataTypes["age"]> {}

Playground Link

CodePudding user response:

You have to use Index access type as . ones do not work in Typescript

type DataTypes = {
  age: number;
  firstName: string;
  lastName: string;
};

abstract class AbstractBase<T extends DataTypes[keyof DataTypes]> {
  data !: T;
}

class AgeComponent extends AbstractBase<DataTypes["age"]> {
}

class FirstNameComponent extends AbstractBase<DataTypes["firstName"]> {}

class LastNameComponent extends AbstractBase<DataTypes["lastName"]> {}


// Test the inference 

new AgeComponent().data // number

new FirstNameComponent().data // string

new LastNameComponent().data // string


Typescript Playground

  • Related