I have type
type User = {
firstName: string,
lastName: string,
age: string
}
I need a function
const result = fun<User>(['firstName', 'lastName'])
I need result
type is a User
with picked firstName
and lastName
. Is it possible to do with typeScript?
Yes, it is possible. I did not came up with this solution myself so all credits go to "drop-george" guy from github:
type User = {
a: number;
b: number;
c: number;
}
type ElementType < T extends ReadonlyArray < unknown > > = T extends ReadonlyArray<
infer ElementType
>
? ElementType
: never
function get<T, K extends (keyof T)[]>(v: T, keys: K): Pick<T, ElementType<K>> {
return v
}
const user: User = {a: 1, b: 2, c: 3}
const v = get(user, ['a', 'b'])
const {a, b, c} = v // ERROR
const {a: a2, b: b2} = v // OK
const {a: a3} = v // OK
get({a: 1, b: 2, c: 3} as User, ['a', 'b', 'otherKey']) // ERROR
UPD: You can just use ElementType<K>
instead of ElementType<typeof keys>
UPD2: AFAIK if you want to make something like fun<User>(['firstName', 'lastName'])
the only 2 ways are:
function get<T, K extends (keyof T)[]>(keys: K): Pick<T, ElementType<K>> {
// return user
}
const user = get<User, ['firstName', 'lastName']>(['firstName', 'lastName'])
function get<T>(): <K extends (keyof T)[]>(keys: K) => Pick<T, ElementType<K>> {
return keys => {
// return user from db
}
}
const user = get<User>()(['firstName', 'lastName'])