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]) => {
}