* changed error message for interface extending primitive type

* moved interface check to different function

* changed part of interface declaration to is extended by interface

Co-authored-by: harsheetkakar <harsheetkakar@bitbucket.com>
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
Harsheet Kakar 2022-06-01 05:17:07 +05:30 committed by GitHub
parent 44b9745942
commit 75f4e95e85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 7 deletions

View File

@ -2478,7 +2478,12 @@ namespace ts {
function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
if (isPrimitiveTypeName(name)) {
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name));
if (isExtendedByInterface(errorLocation)) {
error(errorLocation, Diagnostics.An_interface_cannot_extend_a_primitive_type_like_0_an_interface_can_only_extend_named_types_and_classes, unescapeLeadingUnderscores(name));
}
else {
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name));
}
return true;
}
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
@ -2499,6 +2504,17 @@ namespace ts {
return false;
}
function isExtendedByInterface(node: Node): boolean {
const grandparent = node.parent.parent;
const parentOfGrandparent = grandparent.parent;
if(grandparent && parentOfGrandparent){
const isExtending = isHeritageClause(grandparent) && grandparent.token === SyntaxKind.ExtendsKeyword;
const isInterface = isInterfaceDeclaration(parentOfGrandparent);
return isExtending && isInterface;
}
return false;
}
function maybeMappedType(node: Node, symbol: Symbol) {
const container = findAncestor(node.parent, n =>
isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined;

View File

@ -3475,6 +3475,10 @@
"category": "Error",
"code": 2839
},
"An interface cannot extend a primitive type like '{0}'; an interface can only extend named types and classes": {
"category": "Error",
"code": 2840
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@ -1,4 +1,4 @@
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693: 'string' only refers to a type, but is being used as a value here.
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes
==== tests/cases/compiler/errorLocationForInterfaceExtension.ts (1 errors) ====
@ -6,5 +6,5 @@ tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693:
interface x extends string { }
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
!!! error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes

View File

@ -3,9 +3,11 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(14,5): error TS2411: Prop
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(15,5): error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to 'string' index type '() => string'.
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(19,5): error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to 'string' index type '() => string'.
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to 'string' index type '() => string'.
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(44,21): error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(48,18): error TS2693: 'string' only refers to a type, but is being used as a value here.
==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (5 errors) ====
==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (7 errors) ====
interface a0 {
(): string;
(a, b, c?: string): number;
@ -59,6 +61,17 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Prop
interface d extends a {
}
interface e extends number {
~~~~~~
!!! error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes
}
interface f {
prop: typeof string;
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
}
class c1 implements a {
}
var instance2 = new c1();

View File

@ -42,6 +42,13 @@ interface c extends a, b {
interface d extends a {
}
interface e extends number {
}
interface f {
prop: typeof string;
}
class c1 implements a {
}
var instance2 = new c1();

View File

@ -84,11 +84,22 @@ interface d extends a {
>a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1))
}
interface e extends number {
>e : Symbol(e, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
}
interface f {
>f : Symbol(f, Decl(interfacedeclWithIndexerErrors.ts, 44, 1))
prop: typeof string;
>prop : Symbol(f.prop, Decl(interfacedeclWithIndexerErrors.ts, 46, 13))
}
class c1 implements a {
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1))
>a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1))
}
var instance2 = new c1();
>instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 45, 3))
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
>instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 52, 3))
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1))

View File

@ -70,6 +70,15 @@ interface c extends a, b {
interface d extends a {
}
interface e extends number {
}
interface f {
prop: typeof string;
>prop : any
>string : any
}
class c1 implements a {
>c1 : c1
}

View File

@ -41,6 +41,13 @@ interface c extends a, b {
interface d extends a {
}
interface e extends number {
}
interface f {
prop: typeof string;
}
class c1 implements a {
}
var instance2 = new c1();