Preserve type parameter constraint in emitted mapped types while preserving their distributivity (#54759)

This commit is contained in:
Mateusz Burzyński 2025-05-12 19:54:34 +02:00 committed by GitHub
parent 7156300cee
commit 0fb5e3a8cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 528 additions and 29 deletions

View File

@ -6963,6 +6963,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const questionToken = type.declaration.questionToken ? factory.createToken(type.declaration.questionToken.kind) as QuestionToken | PlusToken | MinusToken : undefined;
let appropriateConstraintTypeNode: TypeNode;
let newTypeVariable: TypeReferenceNode | undefined;
let templateType = getTemplateTypeFromMappedType(type);
const typeParameter = getTypeParameterFromMappedType(type);
// If the mapped type isn't `keyof` constraint-declared, _but_ still has modifiers preserved, and its naive instantiation won't preserve modifiers because its constraint isn't `keyof` constrained, we have work to do
const needsModifierPreservingWrapper = !isMappedTypeWithKeyofConstraintDeclaration(type)
&& !(getModifiersTypeFromMappedType(type).flags & TypeFlags.Unknown)
@ -6972,9 +6974,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// We have a { [P in keyof T]: X }
// We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType`
if (isHomomorphicMappedTypeWithNonHomomorphicInstantiation(type) && context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) {
const newParam = createTypeParameter(createSymbol(SymbolFlags.TypeParameter, "T" as __String));
const name = typeParameterToName(newParam, context);
const newConstraintParam = createTypeParameter(createSymbol(SymbolFlags.TypeParameter, "T" as __String));
const name = typeParameterToName(newConstraintParam, context);
const target = type.target as MappedType;
newTypeVariable = factory.createTypeReferenceNode(name);
templateType = instantiateType(
getTemplateTypeFromMappedType(target),
makeArrayTypeMapper([getTypeParameterFromMappedType(target), getModifiersTypeFromMappedType(target)], [typeParameter, newConstraintParam]),
);
}
appropriateConstraintTypeNode = factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, newTypeVariable || typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
}
@ -6989,9 +6996,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
}
const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
const typeParameterNode = typeParameterToDeclarationWithConstraint(typeParameter, context, appropriateConstraintTypeNode);
// nameType and templateType nodes have to be in the new scope
const cleanup = enterNewScope(context, type.declaration, /*expandedParams*/ undefined, [getDeclaredTypeOfTypeParameter(getSymbolOfDeclaration(type.declaration.typeParameter))]);
const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined;
const templateTypeNode = typeToTypeNodeHelper(removeMissingType(getTemplateTypeFromMappedType(type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context);
const templateTypeNode = typeToTypeNodeHelper(removeMissingType(templateType, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context);
cleanup();
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode, /*members*/ undefined);
context.approximateLength += 10;
const result = setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);

View File

@ -2,8 +2,8 @@
=== computedTypesKeyofNoIndexSignatureType.ts ===
type Compute<A> = { [K in keyof A]: Compute<A[K]>; } & {};
>Compute : { [K in keyof A]: A[K] extends infer T ? { [K_1 in keyof T]: A[K][K_1] extends infer T_1 ? { [K_2 in keyof T_1]: A[K][K_1][K_2] extends infer T_2 ? { [K_3 in keyof T_2]: A[K][K_1][K_2][K_3] extends infer T_3 ? { [K_4 in keyof T_3]: A[K][K_1][K_2][K_3][K_4] extends infer T_4 ? { [K_5 in keyof T_4]: A[K][K_1][K_2][K_3][K_4][K_5] extends infer T_5 ? { [K_6 in keyof T_5]: A[K][K_1][K_2][K_3][K_4][K_5][K_6] extends infer T_6 ? { [K_7 in keyof T_6]: A[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends infer T_7 ? { [K_8 in keyof T_7]: A[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends infer T_8 ? { [K_9 in keyof T_8]: A[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends infer T_9 ? { [K_10 in keyof T_9]: any; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Compute : { [K in keyof A]: A[K] extends infer T ? { [K_1 in keyof T]: T[K_1] extends infer T_1 ? { [K_2 in keyof T_1]: T_1[K_2] extends infer T_2 ? { [K_3 in keyof T_2]: T_2[K_3] extends infer T_3 ? { [K_4 in keyof T_3]: T_3[K_4] extends infer T_4 ? { [K_5 in keyof T_4]: T_4[K_5] extends infer T_5 ? { [K_6 in keyof T_5]: T_5[K_6] extends infer T_6 ? { [K_7 in keyof T_6]: T_6[K_7] extends infer T_7 ? { [K_8 in keyof T_7]: T_7[K_8] extends infer T_8 ? { [K_9 in keyof T_8]: T_8[K_9] extends infer T_9 ? { [K_10 in keyof T_9]: any; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; } : never; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
type EqualsTest<T> = <A>() => A extends T ? 1 : 0;
>EqualsTest : EqualsTest<T>

View File

@ -52,10 +52,10 @@ declare const _default: {
fn: <T extends {
x: T["x"] extends infer T_1 extends {
[x: string]: (...params: unknown[]) => unknown;
} ? { [K in keyof T_1]: T["x"][K]; } : never;
} ? { [K in keyof T_1]: T_1[K]; } : never;
}>(sliceIndex: T) => T["x"] extends infer T_2 extends {
[x: string]: (...params: unknown[]) => unknown;
} ? { [K_1 in keyof T_2]: Parameters<T["x"][K_1]>; } : never;
} ? { [K_1 in keyof T_2]: Parameters<T_2[K_1]>; } : never;
};
};
export default _default;

View File

@ -36,12 +36,12 @@ export default { fn };
=== reexport.ts ===
import test from "./types";
>test : { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T["x"][K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T["x"][K_1]>; } : never; }
> : ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>test : { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T_1[K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T_2[K_1]>; } : never; }
> : ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
export default { test };
>{ test } : { test: { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T["x"][K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T["x"][K_1]>; } : never; }; }
> : ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>test : { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T["x"][K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T["x"][K_1]>; } : never; }
> : ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ test } : { test: { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T_1[K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T_2[K_1]>; } : never; }; }
> : ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>test : { fn: <T extends { x: T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: T_1[K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_2 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K_1 in keyof T_2]: Parameters<T_2[K_1]>; } : never; }
> : ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,109 @@
//// [tests/cases/compiler/declarationEmitMappedTypePreservesTypeParameterConstraint.ts] ////
//// [declarationEmitMappedTypePreservesTypeParameterConstraint.ts]
// repro from https://github.com/microsoft/TypeScript/issues/54560
declare type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];
declare type addQuestionMarks<
T extends object,
R extends keyof T = requiredKeys<T>
> = Pick<Required<T>, R> & Partial<T>;
declare type identity<T> = T;
declare type flatten<T> = identity<{
[k in keyof T]: T[k];
}>;
export declare abstract class ZodType<Output = any> {
readonly _output: Output;
}
export declare class ZodLiteral<T> extends ZodType<T> {}
export declare type ZodTypeAny = ZodType<any>;
export declare type baseObjectOutputType<Shape extends ZodRawShape> = {
[k in keyof Shape]: Shape[k]["_output"];
};
export declare type objectOutputType<Shape extends ZodRawShape> = flatten<
addQuestionMarks<baseObjectOutputType<Shape>>
>;
export declare type ZodRawShape = {
[k: string]: ZodTypeAny;
};
export const buildSchema = <V extends string>(
version: V
): objectOutputType<{
version: ZodLiteral<V>;
}> => ({} as any);
// repro from https://github.com/microsoft/TypeScript/issues/55049
type evaluate<t> = { [k in keyof t]: t[k] } & unknown
export type entryOf<o> = evaluate<
{ [k in keyof o]-?: [k, o[k] & ({} | null)] }[o extends readonly unknown[]
? keyof o & number
: keyof o]
>
export type entriesOf<o extends object> = evaluate<entryOf<o>[]>
export const entriesOf = <o extends object>(o: o) =>
Object.entries(o) as entriesOf<o>
//// [declarationEmitMappedTypePreservesTypeParameterConstraint.js]
"use strict";
// repro from https://github.com/microsoft/TypeScript/issues/54560
Object.defineProperty(exports, "__esModule", { value: true });
exports.entriesOf = exports.buildSchema = void 0;
var buildSchema = function (version) { return ({}); };
exports.buildSchema = buildSchema;
var entriesOf = function (o) {
return Object.entries(o);
};
exports.entriesOf = entriesOf;
//// [declarationEmitMappedTypePreservesTypeParameterConstraint.d.ts]
declare type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];
declare type addQuestionMarks<T extends object, R extends keyof T = requiredKeys<T>> = Pick<Required<T>, R> & Partial<T>;
declare type identity<T> = T;
declare type flatten<T> = identity<{
[k in keyof T]: T[k];
}>;
export declare abstract class ZodType<Output = any> {
readonly _output: Output;
}
export declare class ZodLiteral<T> extends ZodType<T> {
}
export declare type ZodTypeAny = ZodType<any>;
export declare type baseObjectOutputType<Shape extends ZodRawShape> = {
[k in keyof Shape]: Shape[k]["_output"];
};
export declare type objectOutputType<Shape extends ZodRawShape> = flatten<addQuestionMarks<baseObjectOutputType<Shape>>>;
export declare type ZodRawShape = {
[k: string]: ZodTypeAny;
};
export declare const buildSchema: <V extends string>(version: V) => objectOutputType<{
version: ZodLiteral<V>;
}>;
type evaluate<t> = {
[k in keyof t]: t[k];
} & unknown;
export type entryOf<o> = evaluate<{
[k in keyof o]-?: [k, o[k] & ({} | null)];
}[o extends readonly unknown[] ? keyof o & number : keyof o]>;
export type entriesOf<o extends object> = evaluate<entryOf<o>[]>;
export declare const entriesOf: <o extends object>(o: o) => entriesOf<o>;
export {};

View File

@ -0,0 +1,181 @@
//// [tests/cases/compiler/declarationEmitMappedTypePreservesTypeParameterConstraint.ts] ////
=== declarationEmitMappedTypePreservesTypeParameterConstraint.ts ===
// repro from https://github.com/microsoft/TypeScript/issues/54560
declare type requiredKeys<T extends object> = {
>requiredKeys : Symbol(requiredKeys, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 2, 26))
[k in keyof T]: undefined extends T[k] ? never : k;
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 3, 3))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 2, 26))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 2, 26))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 3, 3))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 3, 3))
}[keyof T];
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 2, 26))
declare type addQuestionMarks<
>addQuestionMarks : Symbol(addQuestionMarks, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 4, 11))
T extends object,
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 6, 30))
R extends keyof T = requiredKeys<T>
>R : Symbol(R, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 7, 19))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 6, 30))
>requiredKeys : Symbol(requiredKeys, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 6, 30))
> = Pick<Required<T>, R> & Partial<T>;
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 6, 30))
>R : Symbol(R, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 7, 19))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 6, 30))
declare type identity<T> = T;
>identity : Symbol(identity, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 9, 38))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 11, 22))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 11, 22))
declare type flatten<T> = identity<{
>flatten : Symbol(flatten, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 11, 29))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 13, 21))
>identity : Symbol(identity, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 9, 38))
[k in keyof T]: T[k];
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 14, 3))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 13, 21))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 13, 21))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 14, 3))
}>;
export declare abstract class ZodType<Output = any> {
>ZodType : Symbol(ZodType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 15, 3))
>Output : Symbol(Output, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 17, 38))
readonly _output: Output;
>_output : Symbol(ZodType._output, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 17, 53))
>Output : Symbol(Output, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 17, 38))
}
export declare class ZodLiteral<T> extends ZodType<T> {}
>ZodLiteral : Symbol(ZodLiteral, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 19, 1))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 21, 32))
>ZodType : Symbol(ZodType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 15, 3))
>T : Symbol(T, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 21, 32))
export declare type ZodTypeAny = ZodType<any>;
>ZodTypeAny : Symbol(ZodTypeAny, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 21, 56))
>ZodType : Symbol(ZodType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 15, 3))
export declare type baseObjectOutputType<Shape extends ZodRawShape> = {
>baseObjectOutputType : Symbol(baseObjectOutputType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 23, 46))
>Shape : Symbol(Shape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 25, 41))
>ZodRawShape : Symbol(ZodRawShape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 31, 2))
[k in keyof Shape]: Shape[k]["_output"];
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 26, 3))
>Shape : Symbol(Shape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 25, 41))
>Shape : Symbol(Shape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 25, 41))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 26, 3))
};
export declare type objectOutputType<Shape extends ZodRawShape> = flatten<
>objectOutputType : Symbol(objectOutputType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 27, 2))
>Shape : Symbol(Shape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 29, 37))
>ZodRawShape : Symbol(ZodRawShape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 31, 2))
>flatten : Symbol(flatten, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 11, 29))
addQuestionMarks<baseObjectOutputType<Shape>>
>addQuestionMarks : Symbol(addQuestionMarks, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 4, 11))
>baseObjectOutputType : Symbol(baseObjectOutputType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 23, 46))
>Shape : Symbol(Shape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 29, 37))
>;
export declare type ZodRawShape = {
>ZodRawShape : Symbol(ZodRawShape, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 31, 2))
[k: string]: ZodTypeAny;
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 34, 3))
>ZodTypeAny : Symbol(ZodTypeAny, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 21, 56))
};
export const buildSchema = <V extends string>(
>buildSchema : Symbol(buildSchema, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 37, 12))
>V : Symbol(V, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 37, 28))
version: V
>version : Symbol(version, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 37, 46))
>V : Symbol(V, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 37, 28))
): objectOutputType<{
>objectOutputType : Symbol(objectOutputType, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 27, 2))
version: ZodLiteral<V>;
>version : Symbol(version, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 39, 21))
>ZodLiteral : Symbol(ZodLiteral, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 19, 1))
>V : Symbol(V, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 37, 28))
}> => ({} as any);
// repro from https://github.com/microsoft/TypeScript/issues/55049
type evaluate<t> = { [k in keyof t]: t[k] } & unknown
>evaluate : Symbol(evaluate, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 41, 18))
>t : Symbol(t, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 14))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 22))
>t : Symbol(t, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 14))
>t : Symbol(t, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 14))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 22))
export type entryOf<o> = evaluate<
>entryOf : Symbol(entryOf, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 53))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
>evaluate : Symbol(evaluate, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 41, 18))
{ [k in keyof o]-?: [k, o[k] & ({} | null)] }[o extends readonly unknown[]
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 48, 7))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 48, 7))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
>k : Symbol(k, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 48, 7))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
? keyof o & number
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
: keyof o]
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 47, 20))
>
export type entriesOf<o extends object> = evaluate<entryOf<o>[]>
>entriesOf : Symbol(entriesOf, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 51, 1), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 12))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 53, 22))
>evaluate : Symbol(evaluate, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 41, 18))
>entryOf : Symbol(entryOf, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 45, 53))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 53, 22))
export const entriesOf = <o extends object>(o: o) =>
>entriesOf : Symbol(entriesOf, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 51, 1), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 12))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 26), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 44))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 26), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 44))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 26), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 44))
Object.entries(o) as entriesOf<o>
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 26), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 44))
>entriesOf : Symbol(entriesOf, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 51, 1), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 12))
>o : Symbol(o, Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 26), Decl(declarationEmitMappedTypePreservesTypeParameterConstraint.ts, 55, 44))

View File

@ -0,0 +1,136 @@
//// [tests/cases/compiler/declarationEmitMappedTypePreservesTypeParameterConstraint.ts] ////
=== declarationEmitMappedTypePreservesTypeParameterConstraint.ts ===
// repro from https://github.com/microsoft/TypeScript/issues/54560
declare type requiredKeys<T extends object> = {
>requiredKeys : requiredKeys<T>
> : ^^^^^^^^^^^^^^^
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];
declare type addQuestionMarks<
>addQuestionMarks : addQuestionMarks<T, R>
> : ^^^^^^^^^^^^^^^^^^^^^^
T extends object,
R extends keyof T = requiredKeys<T>
> = Pick<Required<T>, R> & Partial<T>;
declare type identity<T> = T;
>identity : T
> : ^
declare type flatten<T> = identity<{
>flatten : { [k in keyof T]: T[k]; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^
[k in keyof T]: T[k];
}>;
export declare abstract class ZodType<Output = any> {
>ZodType : ZodType<Output>
> : ^^^^^^^^^^^^^^^
readonly _output: Output;
>_output : Output
> : ^^^^^^
}
export declare class ZodLiteral<T> extends ZodType<T> {}
>ZodLiteral : ZodLiteral<T>
> : ^^^^^^^^^^^^^
>ZodType : ZodType<T>
> : ^^^^^^^^^^
export declare type ZodTypeAny = ZodType<any>;
>ZodTypeAny : ZodTypeAny
> : ^^^^^^^^^^
export declare type baseObjectOutputType<Shape extends ZodRawShape> = {
>baseObjectOutputType : baseObjectOutputType<Shape>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[k in keyof Shape]: Shape[k]["_output"];
};
export declare type objectOutputType<Shape extends ZodRawShape> = flatten<
>objectOutputType : addQuestionMarks<baseObjectOutputType<Shape>, requiredKeys<baseObjectOutputType<Shape>>> extends infer T ? { [k in keyof T]: T[k]; } : never
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
addQuestionMarks<baseObjectOutputType<Shape>>
>;
export declare type ZodRawShape = {
>ZodRawShape : ZodRawShape
> : ^^^^^^^^^^^
[k: string]: ZodTypeAny;
>k : string
> : ^^^^^^
};
export const buildSchema = <V extends string>(
>buildSchema : <V extends string>(version: V) => objectOutputType<{ version: ZodLiteral<V>; }>
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
><V extends string>( version: V): objectOutputType<{ version: ZodLiteral<V>;}> => ({} as any) : <V extends string>(version: V) => objectOutputType<{ version: ZodLiteral<V>; }>
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
version: V
>version : V
> : ^
): objectOutputType<{
version: ZodLiteral<V>;
>version : ZodLiteral<V>
> : ^^^^^^^^^^^^^
}> => ({} as any);
>({} as any) : any
>{} as any : any
>{} : {}
> : ^^
// repro from https://github.com/microsoft/TypeScript/issues/55049
type evaluate<t> = { [k in keyof t]: t[k] } & unknown
>evaluate : { [k in keyof t]: t[k]; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^
export type entryOf<o> = evaluate<
>entryOf : { [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o] extends infer T ? { [k in keyof T]: T[k]; } : never
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{ [k in keyof o]-?: [k, o[k] & ({} | null)] }[o extends readonly unknown[]
? keyof o & number
: keyof o]
>
export type entriesOf<o extends object> = evaluate<entryOf<o>[]>
>entriesOf : ({ [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o] extends infer T ? { [k in keyof T]: T[k]; } : never)[]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
export const entriesOf = <o extends object>(o: o) =>
>entriesOf : <o extends object>(o: o) => entriesOf<o>
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
><o extends object>(o: o) => Object.entries(o) as entriesOf<o> : <o extends object>(o: o) => entriesOf<o>
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
>o : o
> : ^
Object.entries(o) as entriesOf<o>
>Object.entries(o) as entriesOf<o> : ({ [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o] extends infer T ? { [k in keyof T]: T[k]; } : never)[]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Object.entries(o) : [string, any][]
> : ^^^^^^^^^^^^^^^
>Object.entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^
>Object : ObjectConstructor
> : ^^^^^^^^^^^^^^^^^
>entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^
>o : o
> : ^

View File

@ -35,4 +35,4 @@ type PrivateMapped<Obj> = {
};
export {};
//// [api.d.ts]
export declare const mappedUnionWithPrivateType: <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T[any][K]; } : never;
export declare const mappedUnionWithPrivateType: <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never;

View File

@ -13,20 +13,20 @@ type PrivateMapped<Obj> = {[K in keyof Obj]: Obj[K]};
=== api.ts ===
import {usePrivateType} from './internal';
>usePrivateType : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T[any][K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>usePrivateType : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
export const mappedUnionWithPrivateType = <T extends unknown[]>(...args: T) => usePrivateType(...args);
>mappedUnionWithPrivateType : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T[any][K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
><T extends unknown[]>(...args: T) => usePrivateType(...args) : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T[any][K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>mappedUnionWithPrivateType : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
><T extends unknown[]>(...args: T) => usePrivateType(...args) : <T extends unknown[]>(...args: T) => T[any] extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never
> : ^ ^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>args : T
> : ^
>usePrivateType(...args) : T[any] extends infer T_1 ? { [K in keyof T_1]: T[any][K]; } : never
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>usePrivateType : <T_1 extends unknown[]>(...args: T_1) => T_1[any] extends infer T_2 ? { [K in keyof T_2]: T_1[any][K]; } : never
> : ^^^^^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>usePrivateType(...args) : T[any] extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>usePrivateType : <T_1 extends unknown[]>(...args: T_1) => T_1[any] extends infer T_2 ? { [K in keyof T_2]: T_2[K]; } : never
> : ^^^^^^^^^^^^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>...args : unknown
> : ^^^^^^^
>args : T

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,61 @@
// @strict: true
// @declaration: true
// @lib: esnext
// repro from https://github.com/microsoft/TypeScript/issues/54560
declare type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];
declare type addQuestionMarks<
T extends object,
R extends keyof T = requiredKeys<T>
> = Pick<Required<T>, R> & Partial<T>;
declare type identity<T> = T;
declare type flatten<T> = identity<{
[k in keyof T]: T[k];
}>;
export declare abstract class ZodType<Output = any> {
readonly _output: Output;
}
export declare class ZodLiteral<T> extends ZodType<T> {}
export declare type ZodTypeAny = ZodType<any>;
export declare type baseObjectOutputType<Shape extends ZodRawShape> = {
[k in keyof Shape]: Shape[k]["_output"];
};
export declare type objectOutputType<Shape extends ZodRawShape> = flatten<
addQuestionMarks<baseObjectOutputType<Shape>>
>;
export declare type ZodRawShape = {
[k: string]: ZodTypeAny;
};
export const buildSchema = <V extends string>(
version: V
): objectOutputType<{
version: ZodLiteral<V>;
}> => ({} as any);
// repro from https://github.com/microsoft/TypeScript/issues/55049
type evaluate<t> = { [k in keyof t]: t[k] } & unknown
export type entryOf<o> = evaluate<
{ [k in keyof o]-?: [k, o[k] & ({} | null)] }[o extends readonly unknown[]
? keyof o & number
: keyof o]
>
export type entriesOf<o extends object> = evaluate<entryOf<o>[]>
export const entriesOf = <o extends object>(o: o) =>
Object.entries(o) as entriesOf<o>