Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript Pick<> type failing: Argument of type '"foo"' is not assignable to parameter of type 'Pick<Bar, "foo">'

I have a use case which I think would be perfect for Typescript's Pick types.

Here's a trimmed down example:

interface CreditCard {
  name: string;
  year: number;
  expired: boolean;
}

function setValue(key: keyof CreditCard, value: Pick<CreditCard, typeof key>) {
  // do stuff...
}

However, when I try calling this function:

setValue("name", "rick");

Typescript (2.3.4) gives the following error:

error TS2345: Argument of type '"rick"' is not assignable to parameter of type 'Pick<CreditCard, "name" | "year" | "expired">'.

Also, I do not have an instance of CreditCard available to pass in as an argument, so changing the function to take a CreditCard as a third parameter is not possible in my use case.

like image 407
Rick Avatar asked Jun 21 '17 13:06

Rick


People also ask

Is not assignable to parameter of type String TypeScript?

The "Type 'string' is not assignable to type" TypeScript error occurs when we try to assign a value of type string to something that expects a different type, e.g. a more specific string literal type or an enum. To solve the error use a const or a type assertion.

Is not assignable to parameter of type?

The error "Argument of type string | undefined is not assignable to parameter of type string" occurs when a possibly undefined value is passed to a function that expects a string . To solve the error, use a type guard to verify the value is a string before passing it to the function.

Is not assignable to type null TS?

The "Type 'string | null' is not assignable to type string" error occurs when a possibly null value is assigned to something that expects a string . To solve the error, use a non-null assertion or a type guard to verify the value is a string before the assignment.

Is not assignable to type null undefined?

The "Type 'undefined' is not assignable to type" error occurs when a possibly undefined value is assigned to something that expects a different type. To solve the error, use the non-null assertion operator or a type guard to verify the value is of the specific type before the assignment.


1 Answers

Pick<Obj, Props> creates a type that looks like Obj with only the properties specified by Props, whereas your example is trying to use it to get the type of a single property, which should instead be done like this: CreditCard[KeyType]

Your setValue function should look like this:

function setValue<K extends keyof CreditCard>(key: K, value: CreditCard[K]) {
  // do stuff...
}

You set up a generic type K which is a string literal type for one or more of the keys of CreditCard. Then you use that type to grab the type of a property off of CreditCard. When the function is invoked, the type system will narrow K as far as it can and use that to figure out a specific type for the value argument.

like image 91
cspotcode Avatar answered Sep 22 '22 15:09

cspotcode