Home > Mobile >  How to get the all types of all the props of interface into one type variable in TypeScript
How to get the all types of all the props of interface into one type variable in TypeScript

Time:09-22

I am building a web application with Typescript. In my code, I got into a situation where I need to get all the types of every prop of an object/ interface into a type variable. Please have a look at the dummy code below.

I have an interface with the following code.

interface ProductForm {
    name: string;
    id: number | string;
    categoryId: number;
    status: ProductStatus // enum
}

As you can see, the above interface has 4 props and they have different types.

I want to have a function as follow.

const updateProductFormField = (name: keyof ProductForm, value: any) => {
   // update the field
}

As you can see in the above code, the function first parameter, name must be one of the props of the ProductForm interface. The second argument has type, any which I am trying to get rid of. The value must be one of the type of types of the props of ProductForm interface. Basically I am trying to get all types of props of ProductForm into one variable like this.

type FormValueTypes = ProductForm['name'] | ProductForm['id'] | ProductForm['categoryId'] | ProductForm['status'];

Then use that type for second argument. But I am hardcoding in the fields in the code above? When a new field is added to the interface, I will have to change that variable too. Is that a more dynamic to achieve the same thing?

CodePudding user response:

Try this.

interface ProductForm {
    name: string;
    id: number | string;
    categoryId: number;
    status: ProductStatus // enum
}

const updateProductFormField = <T extends keyof ProductForm>(name: T, value: ProductForm[T]) => {
   // update the field
}

CodePudding user response:

Normally you'd get all types in values of an interface like below:

interface A {}

interface ProductForm {
    name: string;
    id: number | string;
    categoryId: number;
    status: ProductStatus;
}

const updateProductFormField = (name: keyof ProductForm, value: ProductForm[keyof ProductForm]) => {
   // Type of value here is string | number | ProductStatus
}

However this has the problem that you can do something like:

updateProductFormField('status', 42);

To avoid this you can make the function a generic:

const updateProductFormField = <T extends keyof ProductForm>(name: T, value: ProductForm[T]) => {
}

Playground link

  • Related