问题
I have a function that accepts a variadic list of keys and plucks properties off an object. The particular logic of the function is that if only one key is passed in, that property is returned directly, but if two or more keys are passed in then a tuple of the respective properties is returned.
So I would write something like
const object = {
key1: 1,
key2: 2,
key3: 3
};
const property = pluck('key1'); // 1
const [property1, property3] = pluck('key1', 'key3'); // [1, 3];
But while this works great in JavaScript I can't seem to get something right when I do it in TypeScript. My full TS code is:
type TupleWhenMany<T extends (keyof U)[], U extends object> =
T extends { length: 1 }
? U[T[0]]
: { [I in keyof T]: T[I] extends keyof U ? U[T[I]] : T[I] };
interface Intfc {
key1: number;
key2: number;
key3: string;
};
const object: Intfc = {
key1: 1,
key2: 2,
key3: '3',
};
const pluck = <T extends (keyof Intfc)[]>(...props: T): TupleWhenMany<T, Intfc> => {
if (props.length === 1) {
return object[props[0]];
}
return props.map(prop => object[prop]);
};
Unfortunately the pluck
function gives me errors on the return
lines:
and
If I execute
const a = pluck('key1'); // a: number
const [b, c] = pluck('key2', 'key3'); // b: number; c: string
I get the proper types I expect (the straight type for just a single argument and a tuple of the types for multiple), but I don't know what I need to do to fix the TS compiler errors on the return
statements. I get those to resolve by explicitly asserting the type as TupleWhenMany<T, Intfc>
but this doesn't seem ideal. If I can do it in a more proper way to resolve the TS error I'd like to, I just don't know enough about what is happening under the hood to be able to figure out my best course of action.
来源:https://stackoverflow.com/questions/65137721/synchronize-function-return-type-with-what-function-actually-returns-in-typescri