Skip to content

Commit

Permalink
Don't try to add an implicit undefined for mapped properties outside …
Browse files Browse the repository at this point in the history
…of `strictNullChecks` (#60393)
  • Loading branch information
Andarist authored Dec 19, 2024
1 parent 0dda037 commit 12e205b
Show file tree
Hide file tree
Showing 17 changed files with 721 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6267,7 +6267,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return true;
}
if (requiresAddingUndefined && annotationType) {
annotationType = getOptionalType(annotationType, !isParameter(node));
annotationType = addOptionality(annotationType, !isParameter(node));
}
return !!annotationType && typeNodeIsEquivalentToType(node, type, annotationType) && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks1.ts] ////

//// [createApi.ts]
type Id<T> = {
[K in keyof T]: T[K];
} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
originalArgs?: undefined;
}>;
};
//// [index.ts]
import { createApi } from "./createApi";
const slice = createApi({
endpoints: {
test: {
url: `/user`,
},
},
});
export const { useTestQuery } = slice;
//// [createApi.d.ts]
type Id<T> = {
[K in keyof T]: T[K];
} & {};
export declare function createApi<Definitions>(_: {
endpoints: Definitions;
}): {
[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
originalArgs?: undefined;
}>;
};
export {};
//// [index.d.ts]
export declare const useTestQuery: () => {
status: "uninitialized";
originalArgs?: undefined;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks1.ts] ////

=== createApi.ts ===
type Id<T> = {
>Id : Symbol(Id, Decl(createApi.ts, 0, 0))
>T : Symbol(T, Decl(createApi.ts, 0, 8))

[K in keyof T]: T[K];
>K : Symbol(K, Decl(createApi.ts, 1, 3))
>T : Symbol(T, Decl(createApi.ts, 0, 8))
>T : Symbol(T, Decl(createApi.ts, 0, 8))
>K : Symbol(K, Decl(createApi.ts, 1, 3))

} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
>createApi : Symbol(createApi, Decl(createApi.ts, 2, 7))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))
>_ : Symbol(_, Decl(createApi.ts, 4, 47))
>endpoints : Symbol(endpoints, Decl(createApi.ts, 4, 51))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))

[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
>K : Symbol(K, Decl(createApi.ts, 5, 3))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))
>Capitalize : Symbol(Capitalize, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(createApi.ts, 5, 3))
>Id : Symbol(Id, Decl(createApi.ts, 0, 0))

status: "uninitialized";
>status : Symbol(status, Decl(createApi.ts, 5, 77))

originalArgs?: undefined;
>originalArgs : Symbol(originalArgs, Decl(createApi.ts, 6, 28))

}>;
};

=== index.ts ===
import { createApi } from "./createApi";
>createApi : Symbol(createApi, Decl(index.ts, 0, 8))

const slice = createApi({
>slice : Symbol(slice, Decl(index.ts, 2, 5))
>createApi : Symbol(createApi, Decl(index.ts, 0, 8))

endpoints: {
>endpoints : Symbol(endpoints, Decl(index.ts, 2, 25))

test: {
>test : Symbol(test, Decl(index.ts, 3, 14))

url: `/user`,
>url : Symbol(url, Decl(index.ts, 4, 11))

},
},
});

export const { useTestQuery } = slice;
>useTestQuery : Symbol(useTestQuery, Decl(index.ts, 10, 14))
>slice : Symbol(slice, Decl(index.ts, 2, 5))

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks1.ts] ////

=== createApi.ts ===
type Id<T> = {
>Id : { [K in keyof T]: T[K]; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^

[K in keyof T]: T[K];
} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{ status: "uninitialized"; originalArgs?: undefined; }>; }
> : ^ ^^ ^^ ^^^^^
>_ : { endpoints: Definitions; }
> : ^^^^^^^^^^^^^ ^^^
>endpoints : Definitions
> : ^^^^^^^^^^^

[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
>status : "uninitialized"
> : ^^^^^^^^^^^^^^^

originalArgs?: undefined;
>originalArgs : undefined
> : ^^^^^^^^^

}>;
};

=== index.ts ===
import { createApi } from "./createApi";
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => { status: "uninitialized"; originalArgs?: undefined; }; }
> : ^ ^^ ^^ ^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^

const slice = createApi({
>slice : { useTestQuery: () => { status: "uninitialized"; originalArgs?: undefined; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^
>createApi({ endpoints: { test: { url: `/user`, }, },}) : { useTestQuery: () => { status: "uninitialized"; originalArgs?: undefined; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => { status: "uninitialized"; originalArgs?: undefined; }; }
> : ^ ^^ ^^ ^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^
>{ endpoints: { test: { url: `/user`, }, },} : { endpoints: { test: { url: string; }; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

endpoints: {
>endpoints : { test: { url: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ test: { url: `/user`, }, } : { test: { url: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^

test: {
>test : { url: string; }
> : ^^^^^^^^^^^^^^^^
>{ url: `/user`, } : { url: string; }
> : ^^^^^^^^^^^^^^^^

url: `/user`,
>url : string
> : ^^^^^^
>`/user` : "/user"
> : ^^^^^^^

},
},
});

export const { useTestQuery } = slice;
>useTestQuery : () => { status: "uninitialized"; originalArgs?: undefined; }
> : ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^
>slice : { useTestQuery: () => { status: "uninitialized"; originalArgs?: undefined; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks2.ts] ////

//// [createApi.ts]
type Id<T> = {
[K in keyof T]: T[K];
} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
originalArgs?: any[];
}>;
};
//// [index.ts]
import { createApi } from "./createApi";
const slice = createApi({
endpoints: {
test: {
url: `/user`,
},
},
});
export const { useTestQuery } = slice;
//// [createApi.d.ts]
type Id<T> = {
[K in keyof T]: T[K];
} & {};
export declare function createApi<Definitions>(_: {
endpoints: Definitions;
}): {
[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
originalArgs?: any[];
}>;
};
export {};
//// [index.d.ts]
export declare const useTestQuery: () => {
status: "uninitialized";
originalArgs?: any[];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks2.ts] ////

=== createApi.ts ===
type Id<T> = {
>Id : Symbol(Id, Decl(createApi.ts, 0, 0))
>T : Symbol(T, Decl(createApi.ts, 0, 8))

[K in keyof T]: T[K];
>K : Symbol(K, Decl(createApi.ts, 1, 3))
>T : Symbol(T, Decl(createApi.ts, 0, 8))
>T : Symbol(T, Decl(createApi.ts, 0, 8))
>K : Symbol(K, Decl(createApi.ts, 1, 3))

} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
>createApi : Symbol(createApi, Decl(createApi.ts, 2, 7))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))
>_ : Symbol(_, Decl(createApi.ts, 4, 47))
>endpoints : Symbol(endpoints, Decl(createApi.ts, 4, 51))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))

[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
>K : Symbol(K, Decl(createApi.ts, 5, 3))
>Definitions : Symbol(Definitions, Decl(createApi.ts, 4, 34))
>Capitalize : Symbol(Capitalize, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(createApi.ts, 5, 3))
>Id : Symbol(Id, Decl(createApi.ts, 0, 0))

status: "uninitialized";
>status : Symbol(status, Decl(createApi.ts, 5, 77))

originalArgs?: any[];
>originalArgs : Symbol(originalArgs, Decl(createApi.ts, 6, 28))

}>;
};

=== index.ts ===
import { createApi } from "./createApi";
>createApi : Symbol(createApi, Decl(index.ts, 0, 8))

const slice = createApi({
>slice : Symbol(slice, Decl(index.ts, 2, 5))
>createApi : Symbol(createApi, Decl(index.ts, 0, 8))

endpoints: {
>endpoints : Symbol(endpoints, Decl(index.ts, 2, 25))

test: {
>test : Symbol(test, Decl(index.ts, 3, 14))

url: `/user`,
>url : Symbol(url, Decl(index.ts, 4, 11))

},
},
});

export const { useTestQuery } = slice;
>useTestQuery : Symbol(useTestQuery, Decl(index.ts, 10, 14))
>slice : Symbol(slice, Decl(index.ts, 2, 5))

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//// [tests/cases/compiler/declarationEmitOptionalMappedTypePropertyNoStrictNullChecks2.ts] ////

=== createApi.ts ===
type Id<T> = {
>Id : { [K in keyof T]: T[K]; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^

[K in keyof T]: T[K];
} & {};

export declare function createApi<Definitions>(_: { endpoints: Definitions }): {
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{ status: "uninitialized"; originalArgs?: any[]; }>; }
> : ^ ^^ ^^ ^^^^^
>_ : { endpoints: Definitions; }
> : ^^^^^^^^^^^^^ ^^^
>endpoints : Definitions
> : ^^^^^^^^^^^

[K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => Id<{
status: "uninitialized";
>status : "uninitialized"
> : ^^^^^^^^^^^^^^^

originalArgs?: any[];
>originalArgs : any[]
> : ^^^^^

}>;
};

=== index.ts ===
import { createApi } from "./createApi";
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => { status: "uninitialized"; originalArgs?: any[]; }; }
> : ^ ^^ ^^ ^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^

const slice = createApi({
>slice : { useTestQuery: () => { status: "uninitialized"; originalArgs?: any[]; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^
>createApi({ endpoints: { test: { url: `/user`, }, },}) : { useTestQuery: () => { status: "uninitialized"; originalArgs?: any[]; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^
>createApi : <Definitions>(_: { endpoints: Definitions; }) => { [K in keyof Definitions as `use${Capitalize<K & string>}Query`]: () => { status: "uninitialized"; originalArgs?: any[]; }; }
> : ^ ^^ ^^ ^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^
>{ endpoints: { test: { url: `/user`, }, },} : { endpoints: { test: { url: string; }; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

endpoints: {
>endpoints : { test: { url: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ test: { url: `/user`, }, } : { test: { url: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^

test: {
>test : { url: string; }
> : ^^^^^^^^^^^^^^^^
>{ url: `/user`, } : { url: string; }
> : ^^^^^^^^^^^^^^^^

url: `/user`,
>url : string
> : ^^^^^^
>`/user` : "/user"
> : ^^^^^^^

},
},
});

export const { useTestQuery } = slice;
>useTestQuery : () => { status: "uninitialized"; originalArgs?: any[]; }
> : ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^
>slice : { useTestQuery: () => { status: "uninitialized"; originalArgs?: any[]; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^

Loading

0 comments on commit 12e205b

Please sign in to comment.