type ObjectEntries<T, U = Required<T>> = {
[K in keyof U]: [K, U[K] extends never ? undefined : U[K]]
}[keyof U]
Solution by devshinthant #34934
type ObjectEntries<T, U = Required<T>> = {
[P in keyof U]-?: [P, U[P] extends never ? undefined : U[P]]
}[keyof U]
Solution by 2083335157 #34886
// 数组转联合类型用 [number] 作为下标 ['1', '2']['number'] ---> '1' | '2'
// 对象转联合类型用 [keyof T] 作为下标 {a: 1, b: 2}[keyof T] ---> 1 | 2
// 如果key是可选的,则Required将删除value的undefined类型。
// { a?: undefined } => { a: never }
// { a?: string | undefined } => { a: string }
type ObjectEntries<T> = {
[K in keyof T]-?: [K, [Required<T>[K]] extends [never] ? undefined : Required<T>[K]]
}[keyof T]
Solution by ouzexi #34053
// your answers
type ObjectEntries<T> = { [key in keyof T]-?: [key, Required<T>[key] extends never ? undefined : Required<T>[key]] }[keyof T];
Solution by pea-sys #32930
type ObjectEntries<T extends object> =
{ [K in keyof T]-?: [K, Required<T>[K] extends never ? undefined : Required<T>[K]] }[keyof T]
Required 유틸리티 타입은 key가 옵셔널이면 value의 undefined 타입을 제거한다.
Solution by dev-hobin #32522
type ObjectEntries<T, U= Required<T>> = {
[K in keyof U]-?: [K, U[K] extends never ? undefined : U[K]]
}[keyof U]
Solution by maximallain #32232
// your answers
type RequireObj<T> = {
[P in keyof T]-?: T[P]
}
type _ObjectEntries<T, U extends keyof T> = U extends U ? [U, [T[U]] extends [undefined] ? undefined : T[U]] : never;
type ObjectEntries<T> = _ObjectEntries<RequireObj<T>, keyof T>;
Solution by tarotlwei #31707
type ObjectEntries<T> = Entries<Required<T>>;
type Entries<T> = {
[P in keyof T]: [P, [T[P]] extends [never] ? undefined : T[P]]
}[keyof T];
Solution by sdrjs #31543
type TransformValue<T> = {
[k in keyof T]: [k, T[k]];
}[keyof T];
type ObjectEntries<T, U extends keyof T = keyof T> = U extends any
? TransformValue<
Equal<{ [k in U]: T[k] }, { [k in U]?: undefined }> extends true
? { [k in U]-?: undefined }
: { [k in U]-?: T[k] }
>
: never;
Solution by TRIS-H #31505
Minimal Approach
type ObjectEntries<T> = {
[Prop in keyof T as number]: [Prop, T[Prop] extends undefined ? undefined : Required<T>[Prop]]
} [0]
Solution by fredski02 #31278
type ObjectEntries<T, U = Required<T>> = {
[key in keyof U]: [key, U[key] extends never ? undefined : U[key]];
}[keyof U];
Solution by leejaehyup #30793
The type system implicitly adds | undefined
to the type of optional properties. If we remove the optional specifiers (by using R = Required<T>
) before we build the entry pairs, we avoid these implicitly added undefined
for both the entry values and the union of entries:
type ObjectEntries<T, R = Required<T>> = {
[K in keyof R]: [K, R[K]]
}[keyof R]
At first sight, this solution causes the following check to fail:
Expect<Equal<ObjectEntries<{ key?: undefined }>, ['key', undefined]>>,
The intention of this check seems to be that an explicit undefined
in the type of an optional property should not be removed.
Just quieting the test down by addressing this particular case in the code of the solution is not appropriate as it does not generally keep an explicit undefined
in the type of a property. Instead we should even add one more test case:
Expect<Equal<ObjectEntries<{ key?: string | undefined }>, ['key', string | undefined]>>,
With this additional check, it is even no longer possible to get all checks pass by changing the code of the solution: We have here an explicit type string | undefined
for the optional key
property, whereas the check for Partial<Model>
implicitly changes the type of the name
property to string | undefined
by making it optional. As the type system does not distinguish between an explicit or implicitly added undefined
for optional properties, the problem cannot be solved by changing the code.
Nor it should. As the problem is in the type system, it should be solved there. This can be done by setting the tsConfig
flag
“exactOptionalPropertyTypes”: true
When set, the type system now remembers whether undefined
has implicitly been added for an optional property (in order to prevent assignment of an undefined
value), and Required<T>
no longer removes an explicit undefined
. The solution then passes all checks (including the additional check mentioned above).
Solution by sbr61 #30113
// your answers
type ObjectEntries<T> = { [key in keyof T]-?: [key, Required<T>[key] extends never ? undefined : Required<T>[key]] }[keyof T];
Solution by WeiRu1016 #29979
type Remove<T> = [T] extends [infer A | undefined] ? A : T type ObjectEntries<T, U extends keyof T = keyof T> = { [P in U]-?: [P, Partial<T> extends T ? Remove<T[P]> : T[P]] }[U]
Solution by hesoso #29788
type RemoveUndefined<T> = [T] extends [undefined] ? T : Exclude<T, undefined>
type ObjectEntries<T, K = keyof T> =
K extends keyof T
? [K, T[K] extends Required<T>[K] ? T[K] : RemoveUndefined<T[K]>]
: never
This code passes all test cases.
Solution by tyama711 #29744
type ObjectEntries<T, U = keyof T> = U extends keyof T ? [U, T[U]] : never
Solution by alkkas #29341
type ObjectEntries<T, K extends keyof T = keyof T> = K extends keyof T
? [K, T[K] extends undefined ? T[K] : Exclude<T[K], undefined>]
: never;
Solution by DoGukKim #29199
type ObjectEntries
Solution by sunhk123456 #28955
type RemoveUndefined<T> = [T] extends [undefined] ? T : Exclude<T, undefined>
type ObjectEntries<T> = RemoveUndefined<{
[K in keyof T]: {} extends Pick<T, K> ? [K, RemoveUndefined<T[K]>] : [K, T[K]]
}[keyof T]>
Solution by DoubleWoodLin #28697
type ObjectEntries<T, K = { [P in keyof T]-?: T[P] }> = keyof K extends infer U
? U extends U
? [U, K[U & keyof K] extends never ? undefined : K[U & keyof K]]
: never
: never;
Solution by DoGukKim #28167
type ObjectEntries<T extends { [key: string]: any }> = Partial<{
[Key in keyof T]: [Key, Required<T>[Key]];
}> extends { [key: string]: infer V }
? V extends [infer F, infer R]
? [F, [R] extends [never] ? undefined : R]
: never
: never;
Solution by idebbarh #28163
Main idea: If the key type is optional, the value type needs to erase the undefined type. The specific code is as follows.
/**
* Get the optional type, principle: change a key to optional, and if it still extends the original type, it proves to be optional.
* reference:https://zhuanlan.zhihu.com/p/43206436
*/
type IsOptional<T, K extends keyof T> = {
[K1 in Exclude<keyof T, K>]: T[K1]
} & { K?: T[K] } extends T ? true : false
type RemoveUndefined<T> = [T] extends [undefined] ? T : Exclude<T, undefined>
type ObjectEntries<T> = {
[K in keyof T]-?: [K, IsOptional<T, K> extends true ? RemoveUndefined<T[K]> : T[K]]
}[keyof T]
Solution by NameWjp #28036
// your answers
type ObjectEntries<T, K extends keyof T = keyof T> = K extends unknown ? [K, T[K] extends undefined?T[K]:Required<T>[K]] : never
Solution by AAA611 #27877
// your answers
type ObjectEntries<T, U = Required<T>> = {
[K in keyof U]: [K, U[K] extends never ? undefined : U[K]]
}[keyof U]
Solution by daiki-skm #27849
// your answers
type RemoveUndefined<T> = [T] extends [undefined] ? T : Exclude<T, undefined>
type ObjectEntries<T> = {[K in keyof T] -?: [K, RemoveUndefined<T[K]>]}[keyof T]
Solution by GreattitJY #27683
type RemoveUndefined<T> = [T] extends [undefined] ? T : Exclude<T, undefined>
type ObjectEntries<T, _U extends keyof T = keyof T> =
_U extends _U ? [_U, RemoveUndefined<T[_U]>] : never;
Solution by jjswifty #27630
type UnPartial<T> = Omit<{
[P in keyof T as T[P] extends undefined ? never : P]-? : T[P]
} & {
[P in keyof T as T[P] extends undefined ? P : never] : T[P]
}, never>
type ObjectEntries<T, U = UnPartial<T>> = keyof U extends infer P ?
P extends keyof U ? [P, U[P]] : never : never
Solution by 8471919 #27559
type ObjectEntries<T, K extends keyof T = keyof T> = [keyof T] extends [never]
? []
: K extends K
? [
K, Exclude<T[K], undefined> extends infer R
? [R] extends [never]
? undefined
: R
: never,
]
: []
Solution by jazelly #27395
// your answers
type RemoveUndefined<T> = [T] extends [undefined] ? undefined : T extends undefined ? never : T
type ObjectEntries<T, K extends keyof T = keyof T> = K extends any ? [K, RemoveUndefined<T[K]>] : never
Solution by 774653363 #27168
type ObjectEntries<T, U = Required<T>> = {
[K in keyof U]: [K, U[K] extends never ? undefined : U[K]]
}[keyof U]
Solution by isntkyu #27020