DoneDeal0
DoneDeal0

Reputation: 6257

How to type an object key in Typescript?

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

Answers (3)

Torc
Torc

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

Jérémie B
Jérémie B

Reputation: 11022

try this :

type DataType = "about" | "favorites" | "username";
type Expand<U> = U extends string ? { [key in U]: any } : never

type UpdatedData = Expand<DataType>

TS Playground

Upvotes: 0

yudhiesh
yudhiesh

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

Related Questions