Assume there is a supertype A
:
type A = {
q: {
x1: string;
x2: number;
};
p: number;
};
const aObj: A = {
q: {
x1: 'jj',
x2: 3,
},
p: 5,
};
const fn = <T extends string & keyof A>(path: keyof A): Pick<A, T> => {
return aObj[path];
};
const fn2 = <T extends string & keyof A>(path: keyof A): A[T] => {
return aObj[path];
};
The code above raises the following error TS 2322:
Type "number | { x1: string; x2: number; }" is not assignable to type "A[T]".
Type "number" is not assignable to type "A[T]".
Type "number" is not assignable to type "{ x1: string; x2: number; } & number".
Type "number" is not assignable to type "{ x1: string; x2: number; }".
Now, I want to write a generic function fn
that returns the type of the picked property Pick<A, "p" | "q">
, that is (number) | ({ x1: string, x2: number })
, depending on the specified generic argument.
However, Pick
only returns a subset of all the picked properties of A
.
Replacing Pick
by square brackets does not seem to do the job either.
What is the right way to get the type of the picked property instead of just a subset?
CodePudding user response:
You can have something like:
const fn2 = <T extends keyof A>(path: T): A[T] => {
return aObj[path];
};
You can check this at TypeScript playground
As per your codebase, since there is no corelation between T and typeof path (i.e. keyof A). TypeScript is not able to determine what should be the return type. i.e. for path p
, whether it should be number
or it should be { x1: string, x2: number }
.