Is there any easy to way ensure all keys of an object, are present on another object property?
For example:
export interface Field<T> {
formKey: Extract<keyof T, string>;
label: string;
text: string;
}
export interface FormProps<T> {
initState: T;
fields: Field<T>[];
title: string;
}
const initState = {
name: 'whatever',
description: 'whocares'
}
Is it possible for Typescript to check that for fields
, all keys present in initState
, exist in that array of objects, where those keys get assigned to formKey
?
So if you passed:
const mockExposureProps: FormProps<FormInfo.Exposure> = {
fields: [
{
formKey: "description",
label: "mock-label",
text: "mock-text",
},
],
initState: {
description: "mock-desc",
name: "mock-name",
},
title: "cool title",
};
Typescript would let you know, you didn't also pass an object that has a formKey
of name
EDIT:
The closest I can get is this:
export interface Field<T> {
formKey: Pick<T, keyof T>; // Change occurred here
label: string;
text: string;
}
But then my data structure needs to change to:
const mockExposureProps: FormProps<FormInfo.Exposure> = {
fields: [
{
formKey: { // Change occurred here
description: 'mock-desc',
}
},
label: "mock-label",
text: "mock-text",
},
],
initState: {
description: "mock-desc",
name: "mock-name",
},
title: "cool title",
};
CodePudding user response:
While it is possible to enforce it in a very round about way by doing using a helper function as shown: Make sure array has all types from a union
I don't think that would really work in the context of react and using it within a component. Instead what I would recommend is changing the type definition to:
export interface Field {
label: string;
text: string;
}
export interface FormProps<T> {
initState: T;
fields: Record<keyof T, Field>;
title: string;
}
This way you can easily enforce that each of the keys present in initState must also be present in field.