From 1c5d4e1740eb14673eb5394cec2163168471d2de Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 13 Oct 2021 17:04:33 -0700 Subject: [PATCH] Pass symbol under inspection into checkIndexConstraints (#46350) --- src/compiler/checker.ts | 12 ++-- .../mixinOverMappedTypeNoCrash.symbols | 58 +++++++++++++++++++ .../mixinOverMappedTypeNoCrash.types | 41 +++++++++++++ .../compiler/mixinOverMappedTypeNoCrash.ts | 21 +++++++ 4 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols create mode 100644 tests/baselines/reference/mixinOverMappedTypeNoCrash.types create mode 100644 tests/cases/compiler/mixinOverMappedTypeNoCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1edbb1d4a0..d4588d9551 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34636,7 +34636,7 @@ namespace ts { forEach(node.members, checkSourceElement); if (produceDiagnostics) { const type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); - checkIndexConstraints(type); + checkIndexConstraints(type, type.symbol); checkTypeForDuplicateIndexSignatures(node); checkObjectTypeForDuplicateDeclarations(node); } @@ -38069,7 +38069,7 @@ namespace ts { } } - function checkIndexConstraints(type: Type, isStaticIndex?: boolean) { + function checkIndexConstraints(type: Type, symbol: Symbol, isStaticIndex?: boolean) { const indexInfos = getIndexInfosOfType(type); if (indexInfos.length === 0) { return; @@ -38079,7 +38079,7 @@ namespace ts { checkIndexConstraintForProperty(type, prop, getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true), getNonMissingTypeOfSymbol(prop)); } } - const typeDeclaration = type.symbol.valueDeclaration; + const typeDeclaration = symbol.valueDeclaration; if (typeDeclaration && isClassLike(typeDeclaration)) { for (const member of typeDeclaration.members) { // Only process instance properties with computed names here. Static properties cannot be in conflict with indexers, @@ -38420,8 +38420,8 @@ namespace ts { } if (produceDiagnostics) { - checkIndexConstraints(type); - checkIndexConstraints(staticType, /*isStaticIndex*/ true); + checkIndexConstraints(type, symbol); + checkIndexConstraints(staticType, symbol, /*isStaticIndex*/ true); checkTypeForDuplicateIndexSignatures(node); checkPropertyInitialization(node); } @@ -38848,7 +38848,7 @@ namespace ts { for (const baseType of getBaseTypes(type)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, Diagnostics.Interface_0_incorrectly_extends_interface_1); } - checkIndexConstraints(type); + checkIndexConstraints(type, symbol); } } checkObjectTypeForDuplicateDeclarations(node); diff --git a/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols b/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols new file mode 100644 index 0000000000..01fff6cbf4 --- /dev/null +++ b/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols @@ -0,0 +1,58 @@ +=== tests/cases/compiler/mixinOverMappedTypeNoCrash.ts === +export type ClassInterface = { +>ClassInterface : Symbol(ClassInterface, Decl(mixinOverMappedTypeNoCrash.ts, 0, 0)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) + + [key in keyof C]: C[key]; +>key : Symbol(key, Decl(mixinOverMappedTypeNoCrash.ts, 1, 5)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) +>key : Symbol(key, Decl(mixinOverMappedTypeNoCrash.ts, 1, 5)) +} + +type InstanceInterface = { +>InstanceInterface : Symbol(InstanceInterface, Decl(mixinOverMappedTypeNoCrash.ts, 2, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) + + new(...args: any[]): I +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 5, 8)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) + + prototype: I +>prototype : Symbol(prototype, Decl(mixinOverMappedTypeNoCrash.ts, 5, 26)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) +} + +type Constructor = ClassInterface & InstanceInterface +>Constructor : Symbol(Constructor, Decl(mixinOverMappedTypeNoCrash.ts, 7, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 9, 17)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 9, 34)) +>ClassInterface : Symbol(ClassInterface, Decl(mixinOverMappedTypeNoCrash.ts, 0, 0)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 9, 34)) +>InstanceInterface : Symbol(InstanceInterface, Decl(mixinOverMappedTypeNoCrash.ts, 2, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 9, 17)) + +function cloneClass>(OriginalClass: T): T { +>cloneClass : Symbol(cloneClass, Decl(mixinOverMappedTypeNoCrash.ts, 9, 86)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>Constructor : Symbol(Constructor, Decl(mixinOverMappedTypeNoCrash.ts, 7, 1)) +>OriginalClass : Symbol(OriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 47)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) + + class AnotherOriginalClass extends OriginalClass { +>AnotherOriginalClass : Symbol(AnotherOriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 69)) +>OriginalClass : Symbol(OriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 47)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 13, 20)) + + super(...args) +>super : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 13, 20)) + } + } + return AnotherOriginalClass +>AnotherOriginalClass : Symbol(AnotherOriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 69)) +} diff --git a/tests/baselines/reference/mixinOverMappedTypeNoCrash.types b/tests/baselines/reference/mixinOverMappedTypeNoCrash.types new file mode 100644 index 0000000000..de9532379b --- /dev/null +++ b/tests/baselines/reference/mixinOverMappedTypeNoCrash.types @@ -0,0 +1,41 @@ +=== tests/cases/compiler/mixinOverMappedTypeNoCrash.ts === +export type ClassInterface = { +>ClassInterface : ClassInterface + + [key in keyof C]: C[key]; +} + +type InstanceInterface = { +>InstanceInterface : InstanceInterface + + new(...args: any[]): I +>args : any[] + + prototype: I +>prototype : I +} + +type Constructor = ClassInterface & InstanceInterface +>Constructor : Constructor + +function cloneClass>(OriginalClass: T): T { +>cloneClass : >(OriginalClass: T) => T +>OriginalClass : T + + class AnotherOriginalClass extends OriginalClass { +>AnotherOriginalClass : AnotherOriginalClass +>OriginalClass : {} + + constructor(...args: any[]) { +>args : any[] + + super(...args) +>super(...args) : void +>super : T +>...args : any +>args : any[] + } + } + return AnotherOriginalClass +>AnotherOriginalClass : { new (...args: any[]): AnotherOriginalClass; prototype: cloneClass.AnotherOriginalClass; } & T +} diff --git a/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts b/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts new file mode 100644 index 0000000000..7ca9129a0e --- /dev/null +++ b/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts @@ -0,0 +1,21 @@ +// @noEmit: true + +export type ClassInterface = { + [key in keyof C]: C[key]; +} + +type InstanceInterface = { + new(...args: any[]): I + prototype: I +} + +type Constructor = ClassInterface & InstanceInterface + +function cloneClass>(OriginalClass: T): T { + class AnotherOriginalClass extends OriginalClass { + constructor(...args: any[]) { + super(...args) + } + } + return AnotherOriginalClass +} \ No newline at end of file