// your answers
type GetOptional<T> = {
[key in keyof T as {} extends Pick<T,key> ? key:never]:T[key]
}
Solution by sciencefunq #32916
和 这个挑战逻辑一样
type GetOptional<T, M = Required<T>> = {
[P in keyof (T | M) as Equal<T[P], M[P]> extends true ? never : P]: T[P];
};
Solution by Vampirelee #32603
type GetOptional<T> = {[P in keyof T as T[P] extends Required<T>[P] ? never: P]: T[P]}
// here Required<T>[P] ? never :P remove the required key and pic optional one
Solution by wubrafiq807 #32561
// your answers
type GetOptional<T> = {
[K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K]
}
Solution by laqudee #32361
type GetOptional
Solution by harshtalks #31670
type GetOptional<T> = {
[P in keyof T as T[P] extends Required<T>[P] ? never : P]: T[P];
};
Solution by vipulpathak113 #31320
type GetOptional<T> = {
[K in keyof T as Pick<T, K> extends Required<Pick<T, K>> ? never : K]: T[K]
}
Solution by dreamluo-plus #30719
type Exclude<A, B> = {
[K in keyof A & keyof B]:
A[K] extends B[K] ? never : K
};
type OptionalKeys<T> = Exclude<T, Required<T>>[keyof T];
type GetOptional<T> = {
[K in OptionalKeys<T>]?: T[K]
};
Solution by denysoblohin-okta #30427
type GetOptional<T> = {
[K in keyof T as {[E in K]+?: T[E]} extends {[E in K]:T[E]} ? K : never] : T[K]
}
Solution by gyermakavets #28281
type GetOptional<T> = { [K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K] }
Solution by smileboyi #27332
// 你的答案
type GetOptional<T> = {
[
P in keyof T as
T[P] extends Required<T>[P]
? never
: P
]: T[P];
};
Solution by kiki-zjq #25984
// your answers
type GetOptional<T extends object> = {
[K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K]
}
Solution by studymachiney #24956
type GetOptional<T> = { [P in keyof T as T[P] extends Required<T>[P] ? never : P]: T[P] }; //-?后类型仍相同则为必选字段
Solution by E-uler #24670
type GetOptional<T> = {
[Key in keyof T as T[Key] extends Required<T>[Key] ? never : Key]: T[Key]
}
Solution by NeylonR #24415
type GetOptional<T extends Record<string, any>> = matchOptionalKey<T, GetKeys<T>>;
type GetKeys<T> = {
[k in keyof T]: k;
};
type matchOptionalKey<T extends Record<string, any>, U extends Record<string, any>, k = keyof U> = k extends keyof U ? undefined extends U[k] ? {
[m in k]?: m extends keyof T ? T[m] : never;
} : never : never;
Solution by yolilufei #24357
// 你的答案
type GetOptional<T> = {
[K in keyof T as T[K] extends Required<T>[K]?never:K]:T[K]
}
Solution by walker-hzx #24297
type GetOptional<T> = {[Key in keyof T as {} extends Pick<T, Key> ? Key: never]: T[Key]}
Solution by sabercc #23857
type GetOptional<T> = {
[K in keyof T as {} extends Pick<T, K> ? K : never]: T[K]
}
Solution by snakeUni #23410
// 你的答案
type GetOptional<T> = {
[K in keyof T as ({} extends Pick<T, K> ? K : never)]: T[K]
}
Solution by jxhhdx #22818
type GetOptional<T> = {
[Key in keyof T as T[Key] extends Required<T>[Key] ? never : Key]: T[Key]
}
Solution by drylint #22193
type GetOptional<T extends object> = {[K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K]}
Solution by kfess #21918
type GetRequired<T> = {
[key in keyof T as T[key] extends Required<T>[key] ? key : never] : T[key]
}
type GetOptional<T> = Omit<T, keyof GetRequired<T>>;
Solution by Karamuto #21883
// 你的答案
type GetOptional<T>
= { [K in keyof T as T[K] extends { [K in keyof T]-?: T[K] }[K] ? never : K]: T[K] }
Solution by goddnsgit #21844
type GetOptional<T extends object> = {
[K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K]
}
Solution by jgjgill #21822
type GetOptional<T> = {
[key in keyof T as T extends { [maybeOptKey in key]-?: any } ? never : key]?: T[key]
}
Solution by Drincann #21197
type UnionToIntersection<U> = (
U extends U ? (x: U) => unknown : never
) extends (x: infer R) => unknown
? R
: never;
type GetOptional<T, S extends keyof T = keyof T> = Partial<
UnionToIntersection<
S extends S
? Equal<
Pick<T, S>,
Partial<{
[P in S]: T[S];
}>
> extends true
? Pick<T, S>
: never
: never
>
>;
Solution by so11y #21018
type Not<B extends boolean> = B extends true ? false : true;
type If<B extends boolean, TRet> = B extends true ? TRet : never;
type IsRequired<T, TKey extends keyof T> = Equal<Pick<T, TKey>, Required<Pick<T, TKey>>>;
type IsOptional<T, TKey extends keyof T> = Not<IsRequired<T, TKey>>;
type GetOptional<T> = {
[TKey in keyof T as If<IsOptional<T, TKey>, TKey>] : T[TKey]
}
Solution by mdakram28 #20655
// your answers
type OptionalType<T,P extends keyof T> = {
[K in keyof T ] : T[K]
}[P]
type notOptionalType<T,P extends keyof T> = {
[K in keyof T ]-? : T[K]
}[P]
type GetOptional<T> = {
[K in keyof T as OptionalType<T,K> extends notOptionalType<T,K> ? never : K] : T[K]
}
Solution by YqxLzx #20444
// your answers
type GetOptional<T> = {
[Key in keyof T as Omit<T, Key> extends T ? Key : never]: T[Key];
};
Solution by fengjinlong #20166
type IsOptionalKey<T, K extends keyof T> =
{[P in K]+?: T[P]} extends {[P in K]: T[P]}
? true
: false
type GetOptional<T> = {
[P in keyof T as IsOptionalKey<T, P> extends true ? P : never]: T[P]
}
In order to better explain the solution, I didn't reduce it to a minimum version.
The key point is:
{a: 1} extends {a?: 1}
is true but {a?: 1} extends {a: 1}
is falsePick anyone you like, the 4 statements above is describing the same thing.
Now look at IsOptionalKey
. On the left side of extends
, we build an object with an optional field, much like {a?: 1}
, and on the right side, it's an object with original field a
, which is like {a?: 1}
or {a: 1}
. If the field is optional, so the expression is {a?: 1} extends {a?: 1}
which resolves to true, but if the field is required, the expression would be {a?: 1} extends {a: 1}
, as we stated before, which resolves to false. That's all about how IsOptionalKey
works.
With the util IsOptionalKey
, the remainling is straghtforward and doesn't need more words to explain.
Related:
Solution by zhaoyao91 #20149