Skip to content

Unwrap substitutions both before _and_ after potential simplification #32116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
15 changes: 10 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14826,11 +14826,16 @@ namespace ts {
}

function getNormalizedType(type: Type, writing: boolean): Type {
return isFreshLiteralType(type) ? (<FreshableType>type).regularType :
getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).node ? createTypeReference((<TypeReference>type).target, getTypeArguments(<TypeReference>type)) :
type.flags & TypeFlags.Substitution ? writing ? (<SubstitutionType>type).typeVariable : (<SubstitutionType>type).substitute :
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
type;
do {
const t = isFreshLiteralType(type) ? (<FreshableType>type).regularType :
getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).node ? createTypeReference((<TypeReference>type).target, getTypeArguments(<TypeReference>type)) :
type.flags & TypeFlags.Substitution ? writing ? (<SubstitutionType>type).typeVariable : (<SubstitutionType>type).substitute :
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
type;
if (t === type) break;
type = t;
} while (true);
return type;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//// [indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts]
type AnyFunction = (...args: any[]) => any;
type Params<T> = Parameters<Extract<T, AnyFunction>>;

interface Wrapper<T> {
call<K extends keyof T>(event: K, ...args: Params<T[K]>): void;
}

interface AWrapped {
foo(): void;
}

class A {
foo: Wrapper<AWrapped>;
}

interface BWrapped extends AWrapped {
bar(): void;
}

class B extends A {
foo: Wrapper<BWrapped>;
}

//// [indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var A = /** @class */ (function () {
function A() {
}
return A;
}());
var B = /** @class */ (function (_super) {
__extends(B, _super);
function B() {
return _super !== null && _super.apply(this, arguments) || this;
}
return B;
}(A));
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
=== tests/cases/compiler/indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts ===
type AnyFunction = (...args: any[]) => any;
>AnyFunction : Symbol(AnyFunction, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 0, 0))
>args : Symbol(args, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 0, 20))

type Params<T> = Parameters<Extract<T, AnyFunction>>;
>Params : Symbol(Params, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 0, 43))
>T : Symbol(T, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 1, 12))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 1, 12))
>AnyFunction : Symbol(AnyFunction, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 0, 0))

interface Wrapper<T> {
>Wrapper : Symbol(Wrapper, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 1, 53))
>T : Symbol(T, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 3, 18))

call<K extends keyof T>(event: K, ...args: Params<T[K]>): void;
>call : Symbol(Wrapper.call, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 3, 22))
>K : Symbol(K, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 4, 6))
>T : Symbol(T, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 3, 18))
>event : Symbol(event, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 4, 25))
>K : Symbol(K, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 4, 6))
>args : Symbol(args, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 4, 34))
>Params : Symbol(Params, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 0, 43))
>T : Symbol(T, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 3, 18))
>K : Symbol(K, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 4, 6))
}

interface AWrapped {
>AWrapped : Symbol(AWrapped, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 5, 1))

foo(): void;
>foo : Symbol(AWrapped.foo, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 7, 20))
}

class A {
>A : Symbol(A, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 9, 1))

foo: Wrapper<AWrapped>;
>foo : Symbol(A.foo, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 11, 9))
>Wrapper : Symbol(Wrapper, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 1, 53))
>AWrapped : Symbol(AWrapped, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 5, 1))
}

interface BWrapped extends AWrapped {
>BWrapped : Symbol(BWrapped, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 13, 1))
>AWrapped : Symbol(AWrapped, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 5, 1))

bar(): void;
>bar : Symbol(BWrapped.bar, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 15, 37))
}

class B extends A {
>B : Symbol(B, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 17, 1))
>A : Symbol(A, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 9, 1))

foo: Wrapper<BWrapped>;
>foo : Symbol(B.foo, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 19, 19))
>Wrapper : Symbol(Wrapper, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 1, 53))
>BWrapped : Symbol(BWrapped, Decl(indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts, 13, 1))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
=== tests/cases/compiler/indexedAccessKeyofNestedSimplifiedSubstituteUnwrapped.ts ===
type AnyFunction = (...args: any[]) => any;
>AnyFunction : AnyFunction
>args : any[]

type Params<T> = Parameters<Extract<T, AnyFunction>>;
>Params : Parameters<Extract<T, AnyFunction>>

interface Wrapper<T> {
call<K extends keyof T>(event: K, ...args: Params<T[K]>): void;
>call : <K extends keyof T>(event: K, ...args: Parameters<Extract<T[K], AnyFunction>>) => void
>event : K
>args : Parameters<Extract<T[K], AnyFunction>>
}

interface AWrapped {
foo(): void;
>foo : () => void
}

class A {
>A : A

foo: Wrapper<AWrapped>;
>foo : Wrapper<AWrapped>
}

interface BWrapped extends AWrapped {
bar(): void;
>bar : () => void
}

class B extends A {
>B : B
>A : A

foo: Wrapper<BWrapped>;
>foo : Wrapper<BWrapped>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
type AnyFunction = (...args: any[]) => any;
type Params<T> = Parameters<Extract<T, AnyFunction>>;

interface Wrapper<T> {
call<K extends keyof T>(event: K, ...args: Params<T[K]>): void;
}

interface AWrapped {
foo(): void;
}

class A {
foo: Wrapper<AWrapped>;
}

interface BWrapped extends AWrapped {
bar(): void;
}

class B extends A {
foo: Wrapper<BWrapped>;
}