Type with diverging read/write normalizations still identical to itself (#54033)

This commit is contained in:
Anders Hejlsberg 2023-05-02 06:40:41 -07:00 коммит произвёл GitHub
Родитель ae6393e5eb
Коммит 94564cf073
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 209 добавлений и 0 удалений

Просмотреть файл

@ -20612,6 +20612,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
* * Ternary.False if they are not related.
*/
function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary {
if (originalSource === originalTarget) return Ternary.True;
// Before normalization: if `source` is type an object type, and `target` is primitive,
// skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result
if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) {

Просмотреть файл

@ -0,0 +1,96 @@
=== tests/cases/compiler/identityAndDivergentNormalizedTypes.ts ===
// Repros from #53998
type ApiPost =
>ApiPost : Symbol(ApiPost, Decl(identityAndDivergentNormalizedTypes.ts, 0, 0))
| {
path: "/login";
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 3, 7))
body: {};
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 4, 23))
}
| {
path: "/user";
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 7, 7))
body: { name: string; };
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 8, 22))
>name : Symbol(name, Decl(identityAndDivergentNormalizedTypes.ts, 9, 15))
}
type PostPath = ApiPost["path"];
>PostPath : Symbol(PostPath, Decl(identityAndDivergentNormalizedTypes.ts, 10, 5))
>ApiPost : Symbol(ApiPost, Decl(identityAndDivergentNormalizedTypes.ts, 0, 0))
type PostBody<PATH extends PostPath> = Extract<ApiPost, { path: PATH }>["body"];
>PostBody : Symbol(PostBody, Decl(identityAndDivergentNormalizedTypes.ts, 12, 32))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 14, 14))
>PostPath : Symbol(PostPath, Decl(identityAndDivergentNormalizedTypes.ts, 10, 5))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>ApiPost : Symbol(ApiPost, Decl(identityAndDivergentNormalizedTypes.ts, 0, 0))
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 14, 57))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 14, 14))
const post = <PATH extends PostPath>(
>post : Symbol(post, Decl(identityAndDivergentNormalizedTypes.ts, 16, 5))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 16, 14))
>PostPath : Symbol(PostPath, Decl(identityAndDivergentNormalizedTypes.ts, 10, 5))
path: PATH,
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 16, 37))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 16, 14))
{body, ...options}: Omit<RequestInit, 'body'> & {body: PostBody<PATH>}
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 18, 5))
>options : Symbol(options, Decl(identityAndDivergentNormalizedTypes.ts, 18, 10))
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
>RequestInit : Symbol(RequestInit, Decl(lib.dom.d.ts, --, --))
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 18, 53))
>PostBody : Symbol(PostBody, Decl(identityAndDivergentNormalizedTypes.ts, 12, 32))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 16, 14))
) => {
}
const tmp = <PATH extends PostPath>(
>tmp : Symbol(tmp, Decl(identityAndDivergentNormalizedTypes.ts, 22, 5))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 22, 13))
>PostPath : Symbol(PostPath, Decl(identityAndDivergentNormalizedTypes.ts, 10, 5))
path: PATH,
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 22, 36))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 22, 13))
body: PostBody<PATH>
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 23, 13))
>PostBody : Symbol(PostBody, Decl(identityAndDivergentNormalizedTypes.ts, 12, 32))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 22, 13))
) => {
post<PATH>(path, { body })
>post : Symbol(post, Decl(identityAndDivergentNormalizedTypes.ts, 16, 5))
>PATH : Symbol(PATH, Decl(identityAndDivergentNormalizedTypes.ts, 22, 13))
>path : Symbol(path, Decl(identityAndDivergentNormalizedTypes.ts, 22, 36))
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 26, 20))
}
function fx1<P extends PostPath>(x: { body: PostBody<P> }, y: { body: PostBody<P> }) {
>fx1 : Symbol(fx1, Decl(identityAndDivergentNormalizedTypes.ts, 27, 1))
>P : Symbol(P, Decl(identityAndDivergentNormalizedTypes.ts, 29, 13))
>PostPath : Symbol(PostPath, Decl(identityAndDivergentNormalizedTypes.ts, 10, 5))
>x : Symbol(x, Decl(identityAndDivergentNormalizedTypes.ts, 29, 33))
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 29, 37))
>PostBody : Symbol(PostBody, Decl(identityAndDivergentNormalizedTypes.ts, 12, 32))
>P : Symbol(P, Decl(identityAndDivergentNormalizedTypes.ts, 29, 13))
>y : Symbol(y, Decl(identityAndDivergentNormalizedTypes.ts, 29, 58))
>body : Symbol(body, Decl(identityAndDivergentNormalizedTypes.ts, 29, 63))
>PostBody : Symbol(PostBody, Decl(identityAndDivergentNormalizedTypes.ts, 12, 32))
>P : Symbol(P, Decl(identityAndDivergentNormalizedTypes.ts, 29, 13))
x = y;
>x : Symbol(x, Decl(identityAndDivergentNormalizedTypes.ts, 29, 33))
>y : Symbol(y, Decl(identityAndDivergentNormalizedTypes.ts, 29, 58))
}

Просмотреть файл

@ -0,0 +1,76 @@
=== tests/cases/compiler/identityAndDivergentNormalizedTypes.ts ===
// Repros from #53998
type ApiPost =
>ApiPost : { path: "/login"; body: {}; } | { path: "/user"; body: { name: string;}; }
| {
path: "/login";
>path : "/login"
body: {};
>body : {}
}
| {
path: "/user";
>path : "/user"
body: { name: string; };
>body : { name: string; }
>name : string
}
type PostPath = ApiPost["path"];
>PostPath : "/login" | "/user"
type PostBody<PATH extends PostPath> = Extract<ApiPost, { path: PATH }>["body"];
>PostBody : PostBody<PATH>
>path : PATH
const post = <PATH extends PostPath>(
>post : <PATH extends "/login" | "/user">(path: PATH, { body, ...options }: Omit<RequestInit, "body"> & { body: PostBody<PATH>; }) => void
><PATH extends PostPath>( path: PATH, {body, ...options}: Omit<RequestInit, 'body'> & {body: PostBody<PATH>}) => {} : <PATH extends "/login" | "/user">(path: PATH, { body, ...options }: Omit<RequestInit, "body"> & { body: PostBody<PATH>; }) => void
path: PATH,
>path : PATH
{body, ...options}: Omit<RequestInit, 'body'> & {body: PostBody<PATH>}
>body : PostBody<PATH>
>options : { cache?: RequestCache | undefined; credentials?: RequestCredentials | undefined; headers?: HeadersInit | undefined; integrity?: string | undefined; keepalive?: boolean | undefined; method?: string | undefined; mode?: RequestMode | undefined; redirect?: RequestRedirect | undefined; referrer?: string | undefined; referrerPolicy?: ReferrerPolicy | undefined; signal?: AbortSignal | null | undefined; window?: null | undefined; }
>body : PostBody<PATH>
) => {
}
const tmp = <PATH extends PostPath>(
>tmp : <PATH extends "/login" | "/user">(path: PATH, body: PostBody<PATH>) => void
><PATH extends PostPath>( path: PATH, body: PostBody<PATH>) => { post<PATH>(path, { body })} : <PATH extends "/login" | "/user">(path: PATH, body: PostBody<PATH>) => void
path: PATH,
>path : PATH
body: PostBody<PATH>
>body : PostBody<PATH>
) => {
post<PATH>(path, { body })
>post<PATH>(path, { body }) : void
>post : <PATH extends "/login" | "/user">(path: PATH, { body, ...options }: Omit<RequestInit, "body"> & { body: PostBody<PATH>; }) => void
>path : PATH
>{ body } : { body: PostBody<PATH>; }
>body : PostBody<PATH>
}
function fx1<P extends PostPath>(x: { body: PostBody<P> }, y: { body: PostBody<P> }) {
>fx1 : <P extends "/login" | "/user">(x: { body: PostBody<P>;}, y: { body: PostBody<P>;}) => void
>x : { body: PostBody<P>; }
>body : PostBody<P>
>y : { body: PostBody<P>; }
>body : PostBody<P>
x = y;
>x = y : { body: PostBody<P>; }
>x : { body: PostBody<P>; }
>y : { body: PostBody<P>; }
}

Просмотреть файл

@ -0,0 +1,35 @@
// @strict: true
// @noEmit: true
// Repros from #53998
type ApiPost =
| {
path: "/login";
body: {};
}
| {
path: "/user";
body: { name: string; };
}
type PostPath = ApiPost["path"];
type PostBody<PATH extends PostPath> = Extract<ApiPost, { path: PATH }>["body"];
const post = <PATH extends PostPath>(
path: PATH,
{body, ...options}: Omit<RequestInit, 'body'> & {body: PostBody<PATH>}
) => {
}
const tmp = <PATH extends PostPath>(
path: PATH,
body: PostBody<PATH>
) => {
post<PATH>(path, { body })
}
function fx1<P extends PostPath>(x: { body: PostBody<P> }, y: { body: PostBody<P> }) {
x = y;
}