Reputation: 6257
I have a simple function that takes an object in parameter. In order to receive only valid data, I need to type the key of the object as such:
type DataType = "about" | "favorites" | "username";
type UpdatedData = { [key in DataType]: any };
function onSave (updatedData: UpdatedData){
//do stuff
}
// in a component
const onClickSave = () => onSave({ "about": text });
Typescript throws the following error:
Argument of type '{ about: text; }' is not assignable to parameter of type 'UpdatedData'. Type '{ about: text; }' is missing the following properties from type 'UpdatedData': favorites, username
How to fix this? Of course, I could write [key: string]
instead of [key in DataType]
but the typing would be useless then.
Upvotes: 8
Views: 10168
Reputation: 1312
For what it's worth, the same thing that @JérémieB provided can be accomplished with the following const assertion:
const DataType = ["about", "favorites", "username"] as const;
type UpdatedData = { [key in typeof DataType]?: any };
But as @yudhiesh mentioned, making each field optional allows more than one field to be present (as well as no fields at all). If you're in a scenario where only one key should be allowed from a list of expected key values, then I'd recommend taking a look at this post instead: Enforce Typescript object has exactly one key from a set
Upvotes: 0
Reputation: 11022
try this :
type DataType = "about" | "favorites" | "username";
type Expand<U> = U extends string ? { [key in U]: any } : never
type UpdatedData = Expand<DataType>
Upvotes: 0
Reputation: 6799
As the properties of UpdatedData
can be optional just add in a ?
to make them optional.
Edit:
As @Jérémie B mentioned an empty {}
is still permitted with this.
type DataType = "about" | "favorites" | "username";
type UpdatedData = { [key in DataType]?: any };
function onSave (updatedData: UpdatedData){
}
const text = "hello"
const onClickSave = () => onSave({ "about": text });
Upvotes: 11