Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1367,25 +1367,26 @@ func (b *nodeBuilderImpl) createMappedTypeNodeFromType(t *Type) *ast.TypeNode {
}
var appropriateConstraintTypeNode *ast.Node
var newTypeVariable *ast.Node
templateType := b.ch.getTemplateTypeFromMappedType(t)
typeParameter := b.ch.getTypeParameterFromMappedType(t)

// 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
needsModifierPreservingWrapper := !b.ch.isMappedTypeWithKeyofConstraintDeclaration(t) &&
b.ch.getModifiersTypeFromMappedType(t).flags&TypeFlagsUnknown == 0 &&
b.ctx.flags&nodebuilder.FlagsGenerateNamesForShadowedTypeParams != 0 &&
!(b.ch.getConstraintTypeFromMappedType(t).flags&TypeFlagsTypeParameter != 0 && b.ch.getConstraintOfTypeParameter(b.ch.getConstraintTypeFromMappedType(t)).flags&TypeFlagsIndex != 0)

cleanup := b.enterNewScope(mapped.declaration.AsNode(), nil, []*Type{b.ch.getTypeParameterFromMappedType(t)}, nil, nil)
defer cleanup()

if b.ch.isMappedTypeWithKeyofConstraintDeclaration(t) {
// 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 b.ctx.flags&nodebuilder.FlagsGenerateNamesForShadowedTypeParams != 0 && b.isHomomorphicMappedTypeWithNonHomomorphicInstantiation(mapped) {
newParam := b.ch.newTypeParameter(
newConstraintParam := b.ch.newTypeParameter(
b.ch.newSymbol(ast.SymbolFlagsTypeParameter, "T"),
)
name := b.typeParameterToName(newParam)
name := b.typeParameterToName(newConstraintParam)
target := t.Target()
newTypeVariable = b.f.NewTypeReferenceNode(name.AsNode(), nil)
templateType = b.ch.instantiateType(b.ch.getTemplateTypeFromMappedType(target), newTypeMapper([]*Type{b.ch.getTypeParameterFromMappedType(target), b.ch.getModifiersTypeFromMappedType(target)}, []*Type{typeParameter, newConstraintParam}))
}
indexTarget := newTypeVariable
if indexTarget == nil {
Expand All @@ -1405,15 +1406,18 @@ func (b *nodeBuilderImpl) createMappedTypeNodeFromType(t *Type) *ast.TypeNode {
appropriateConstraintTypeNode = b.typeToTypeNode(b.ch.getConstraintTypeFromMappedType(t))
}

typeParameterNode := b.typeParameterToDeclarationWithConstraint(b.ch.getTypeParameterFromMappedType(t), appropriateConstraintTypeNode)
// nameType and templateType nodes have to be in the new scope
cleanup := b.enterNewScope(mapped.declaration.AsNode(), nil, []*Type{b.ch.getTypeParameterFromMappedType(t)}, nil, nil)
typeParameterNode := b.typeParameterToDeclarationWithConstraint(typeParameter, appropriateConstraintTypeNode)
var nameTypeNode *ast.Node
if mapped.declaration.NameType != nil {
nameTypeNode = b.typeToTypeNode(b.ch.getNameTypeFromMappedType(t))
}
templateTypeNode := b.typeToTypeNode(b.ch.removeMissingType(
b.ch.getTemplateTypeFromMappedType(t),
templateType,
getMappedTypeModifiers(t)&MappedTypeModifiersIncludeOptional != 0,
))
cleanup()
result := b.f.NewMappedTypeNode(
readonlyToken,
typeParameterNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

=== 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>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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;
}>(sliceIndex: T) => T["x"] extends infer T_1 extends {
} ? { [K in keyof T_1]: T_1[K]; } : never;
}>(sliceIndex: T) => T["x"] extends infer T_2 extends {
[x: string]: (...params: unknown[]) => unknown;
} ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : never;
} ? { [K in keyof T_2]: Parameters<T_2[K]>; } : never;
};
};
export default _default;
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@
exports.default = { test: types_1.default };


@@= skipped -25, +25 lines =@@
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 {
+ } ? { [K in keyof T_1]: T["x"][K]; } : never;
+ }>(sliceIndex: T) => T["x"] extends infer T_1 extends {
@@= skipped -28, +28 lines =@@
} ? { [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;
+ } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : never;
+ } ? { [K in keyof T_2]: Parameters<T_2[K]>; } : never;
};
};
export default _default;
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ 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_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : 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_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : never; }

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
=== 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_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["x"][K]; } : never; }>(sliceIndex: T) => T["x"] extends infer T_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : never; }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems there is still some issue (or just a diff?) when it comes to renaming the K type parameters in mapped types. I think this can be tackled later


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_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; }
+>{ 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_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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_1 extends { [x: string]: (...params: unknown[]) => unknown; } ? { [K in keyof T_1]: Parameters<T["x"][K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : 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 in keyof T_2]: Parameters<T_2[K]>; } : never; }
Original file line number Diff line number Diff line change
Expand Up @@ -94,67 +94,13 @@ export declare type ZodRawShape = {
};
export declare const buildSchema: <V extends string>(version: V) => addQuestionMarks<baseObjectOutputType<{
version: ZodLiteral<V>;
}>, undefined extends V ? never : "version"> extends infer T ? { [k in keyof T]: addQuestionMarks<baseObjectOutputType<{
version: ZodLiteral<V>;
}>, undefined extends V ? never : "version">[k]; } : never;
}>, undefined extends V ? never : "version"> extends infer T ? { [k in keyof T]: T[k]; } : never;
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) => ({ [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]: { [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o][k]; } : never)[];
export declare const entriesOf: <o extends object>(o: o) => ({ [k in keyof o]-?: [k, o[k] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o] extends infer T ? { [k in keyof T]: T[k]; } : never)[];
export {};


//// [DtsFileErrors]


declarationEmitMappedTypePreservesTypeParameterConstraint.d.ts(24,82): error TS2536: Type 'k' cannot be used to index type 'addQuestionMarks<baseObjectOutputType<{ version: ZodLiteral<V>; }>, undefined extends V ? never : "version">'.
declarationEmitMappedTypePreservesTypeParameterConstraint.d.ts(34,210): error TS2536: Type 'k' cannot be used to index type '{ [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o]'.


==== declarationEmitMappedTypePreservesTypeParameterConstraint.d.ts (2 errors) ====
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) => addQuestionMarks<baseObjectOutputType<{
version: ZodLiteral<V>;
}>, undefined extends V ? never : "version"> extends infer T ? { [k in keyof T]: addQuestionMarks<baseObjectOutputType<{
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
version: ZodLiteral<V>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~
}>, undefined extends V ? never : "version">[k]; } : never;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2536: Type 'k' cannot be used to index type 'addQuestionMarks<baseObjectOutputType<{ version: ZodLiteral<V>; }>, undefined extends V ? never : "version">'.
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) => ({ [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]: { [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o][k]; } : never)[];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2536: Type 'k' cannot be used to index type '{ [k_1 in keyof o]-?: [k_1, o[k_1] & ({} | null)]; }[o extends readonly unknown[] ? keyof o & number : keyof o]'.
export {};

Loading