check computed property names in overloads (#52427)

This commit is contained in:
Zzzen
2023-03-08 09:20:33 -08:00
committed by GitHub
parent 746a6feb2e
commit 0ce551752d
6 changed files with 583 additions and 2 deletions
+1 -2
View File
@@ -38763,8 +38763,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// both are private identifiers
isPrivateIdentifier(node.name) && isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText ||
// Both are computed property names
// TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
isComputedPropertyName(node.name) && isComputedPropertyName(subsequentName) ||
isComputedPropertyName(node.name) && isComputedPropertyName(subsequentName) && isTypeIdenticalTo(checkComputedPropertyName(node.name), checkComputedPropertyName(subsequentName)) ||
// Both are literal property names that are the same.
isPropertyNameLiteral(node.name) && isPropertyNameLiteral(subsequentName) &&
getEscapedTextOfIdentifierOrLiteral(node.name) === getEscapedTextOfIdentifierOrLiteral(subsequentName)
@@ -0,0 +1,91 @@
tests/cases/compiler/overloadsWithComputedNames.ts(4,5): error TS2389: Function implementation name must be '["B"]'.
tests/cases/compiler/overloadsWithComputedNames.ts(14,5): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/overloadsWithComputedNames.ts(16,5): error TS2389: Function implementation name must be '["bar"]'.
tests/cases/compiler/overloadsWithComputedNames.ts(28,5): error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
tests/cases/compiler/overloadsWithComputedNames.ts(29,5): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/overloadsWithComputedNames.ts(35,5): error TS1169: A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.
tests/cases/compiler/overloadsWithComputedNames.ts(42,5): error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
tests/cases/compiler/overloadsWithComputedNames.ts(47,5): error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
tests/cases/compiler/overloadsWithComputedNames.ts(52,5): error TS2391: Function implementation is missing or not immediately following the declaration.
==== tests/cases/compiler/overloadsWithComputedNames.ts (9 errors) ====
// https://github.com/microsoft/TypeScript/issues/52329
class Person {
["B"](a: number): string;
["A"](a: string|number): number | string {
~~~~~
!!! error TS2389: Function implementation name must be '["B"]'.
return 0;
}
}
let p = new Person();
p.A(0)
p.B(0)
// https://github.com/microsoft/TypeScript/issues/17345
class C {
["foo"](): void
~~~~~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
["bar"](): void;
["foo"]() {
~~~~~~~
!!! error TS2389: Function implementation name must be '["bar"]'.
return 0;
}
}
declare const uniqueSym: unique symbol;
declare const uniqueSym2: unique symbol;
declare const sym: symbol;
declare const strUnion: 'foo' | 'bar';
class C1 {
[sym](): void; // should error
~~~~~
!!! error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
[uniqueSym2](): void; // should error
~~~~~~~~~~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
[uniqueSym](): void;
[uniqueSym]() { }
}
interface I1 {
[sym](): void; // should error
~~~~~
!!! error TS1169: A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.
[uniqueSym2](): void;
[uniqueSym](): void;
[uniqueSym](): void;
}
class C2 {
[strUnion](): void; // should error
~~~~~~~~~~
!!! error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
[strUnion]() { }
}
class I2 {
[strUnion](): void; // should error
~~~~~~~~~~
!!! error TS1168: A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.
[strUnion]() { }
}
class C3 {
[1](): void; // should error
~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
[2](): void;
[2]() { }
}
interface I3 {
[1](): void;
[2](): void;
[2](): void;
}
@@ -0,0 +1,109 @@
//// [overloadsWithComputedNames.ts]
// https://github.com/microsoft/TypeScript/issues/52329
class Person {
["B"](a: number): string;
["A"](a: string|number): number | string {
return 0;
}
}
let p = new Person();
p.A(0)
p.B(0)
// https://github.com/microsoft/TypeScript/issues/17345
class C {
["foo"](): void
["bar"](): void;
["foo"]() {
return 0;
}
}
declare const uniqueSym: unique symbol;
declare const uniqueSym2: unique symbol;
declare const sym: symbol;
declare const strUnion: 'foo' | 'bar';
class C1 {
[sym](): void; // should error
[uniqueSym2](): void; // should error
[uniqueSym](): void;
[uniqueSym]() { }
}
interface I1 {
[sym](): void; // should error
[uniqueSym2](): void;
[uniqueSym](): void;
[uniqueSym](): void;
}
class C2 {
[strUnion](): void; // should error
[strUnion]() { }
}
class I2 {
[strUnion](): void; // should error
[strUnion]() { }
}
class C3 {
[1](): void; // should error
[2](): void;
[2]() { }
}
interface I3 {
[1](): void;
[2](): void;
[2](): void;
}
//// [overloadsWithComputedNames.js]
// https://github.com/microsoft/TypeScript/issues/52329
var Person = /** @class */ (function () {
function Person() {
}
Person.prototype["A"] = function (a) {
return 0;
};
return Person;
}());
var p = new Person();
p.A(0);
p.B(0);
// https://github.com/microsoft/TypeScript/issues/17345
var C = /** @class */ (function () {
function C() {
}
C.prototype["foo"] = function () {
return 0;
};
return C;
}());
var C1 = /** @class */ (function () {
function C1() {
}
C1.prototype[uniqueSym] = function () { };
return C1;
}());
var C2 = /** @class */ (function () {
function C2() {
}
C2.prototype[strUnion] = function () { };
return C2;
}());
var I2 = /** @class */ (function () {
function I2() {
}
I2.prototype[strUnion] = function () { };
return I2;
}());
var C3 = /** @class */ (function () {
function C3() {
}
C3.prototype[2] = function () { };
return C3;
}());
@@ -0,0 +1,159 @@
=== tests/cases/compiler/overloadsWithComputedNames.ts ===
// https://github.com/microsoft/TypeScript/issues/52329
class Person {
>Person : Symbol(Person, Decl(overloadsWithComputedNames.ts, 0, 0))
["B"](a: number): string;
>["B"] : Symbol(Person["B"], Decl(overloadsWithComputedNames.ts, 1, 14))
>"B" : Symbol(Person["B"], Decl(overloadsWithComputedNames.ts, 1, 14))
>a : Symbol(a, Decl(overloadsWithComputedNames.ts, 2, 10))
["A"](a: string|number): number | string {
>["A"] : Symbol(Person["A"], Decl(overloadsWithComputedNames.ts, 2, 29))
>"A" : Symbol(Person["A"], Decl(overloadsWithComputedNames.ts, 2, 29))
>a : Symbol(a, Decl(overloadsWithComputedNames.ts, 3, 10))
return 0;
}
}
let p = new Person();
>p : Symbol(p, Decl(overloadsWithComputedNames.ts, 7, 3))
>Person : Symbol(Person, Decl(overloadsWithComputedNames.ts, 0, 0))
p.A(0)
>p.A : Symbol(Person["A"], Decl(overloadsWithComputedNames.ts, 2, 29))
>p : Symbol(p, Decl(overloadsWithComputedNames.ts, 7, 3))
>A : Symbol(Person["A"], Decl(overloadsWithComputedNames.ts, 2, 29))
p.B(0)
>p.B : Symbol(Person["B"], Decl(overloadsWithComputedNames.ts, 1, 14))
>p : Symbol(p, Decl(overloadsWithComputedNames.ts, 7, 3))
>B : Symbol(Person["B"], Decl(overloadsWithComputedNames.ts, 1, 14))
// https://github.com/microsoft/TypeScript/issues/17345
class C {
>C : Symbol(C, Decl(overloadsWithComputedNames.ts, 9, 6))
["foo"](): void
>["foo"] : Symbol(C["foo"], Decl(overloadsWithComputedNames.ts, 12, 9), Decl(overloadsWithComputedNames.ts, 14, 20))
>"foo" : Symbol(C["foo"], Decl(overloadsWithComputedNames.ts, 12, 9), Decl(overloadsWithComputedNames.ts, 14, 20))
["bar"](): void;
>["bar"] : Symbol(C["bar"], Decl(overloadsWithComputedNames.ts, 13, 19))
>"bar" : Symbol(C["bar"], Decl(overloadsWithComputedNames.ts, 13, 19))
["foo"]() {
>["foo"] : Symbol(C["foo"], Decl(overloadsWithComputedNames.ts, 12, 9), Decl(overloadsWithComputedNames.ts, 14, 20))
>"foo" : Symbol(C["foo"], Decl(overloadsWithComputedNames.ts, 12, 9), Decl(overloadsWithComputedNames.ts, 14, 20))
return 0;
}
}
declare const uniqueSym: unique symbol;
>uniqueSym : Symbol(uniqueSym, Decl(overloadsWithComputedNames.ts, 20, 13))
declare const uniqueSym2: unique symbol;
>uniqueSym2 : Symbol(uniqueSym2, Decl(overloadsWithComputedNames.ts, 21, 13))
declare const sym: symbol;
>sym : Symbol(sym, Decl(overloadsWithComputedNames.ts, 22, 13))
declare const strUnion: 'foo' | 'bar';
>strUnion : Symbol(strUnion, Decl(overloadsWithComputedNames.ts, 24, 13))
class C1 {
>C1 : Symbol(C1, Decl(overloadsWithComputedNames.ts, 24, 38))
[sym](): void; // should error
>[sym] : Symbol(C1[sym], Decl(overloadsWithComputedNames.ts, 26, 10))
>sym : Symbol(sym, Decl(overloadsWithComputedNames.ts, 22, 13))
[uniqueSym2](): void; // should error
>[uniqueSym2] : Symbol(C1[uniqueSym2], Decl(overloadsWithComputedNames.ts, 27, 18))
>uniqueSym2 : Symbol(uniqueSym2, Decl(overloadsWithComputedNames.ts, 21, 13))
[uniqueSym](): void;
>[uniqueSym] : Symbol(C1[uniqueSym], Decl(overloadsWithComputedNames.ts, 28, 25), Decl(overloadsWithComputedNames.ts, 29, 24))
>uniqueSym : Symbol(uniqueSym, Decl(overloadsWithComputedNames.ts, 20, 13))
[uniqueSym]() { }
>[uniqueSym] : Symbol(C1[uniqueSym], Decl(overloadsWithComputedNames.ts, 28, 25), Decl(overloadsWithComputedNames.ts, 29, 24))
>uniqueSym : Symbol(uniqueSym, Decl(overloadsWithComputedNames.ts, 20, 13))
}
interface I1 {
>I1 : Symbol(I1, Decl(overloadsWithComputedNames.ts, 31, 1))
[sym](): void; // should error
>[sym] : Symbol(I1[sym], Decl(overloadsWithComputedNames.ts, 33, 14))
>sym : Symbol(sym, Decl(overloadsWithComputedNames.ts, 22, 13))
[uniqueSym2](): void;
>[uniqueSym2] : Symbol(I1[uniqueSym2], Decl(overloadsWithComputedNames.ts, 34, 18))
>uniqueSym2 : Symbol(uniqueSym2, Decl(overloadsWithComputedNames.ts, 21, 13))
[uniqueSym](): void;
>[uniqueSym] : Symbol(I1[uniqueSym], Decl(overloadsWithComputedNames.ts, 35, 25), Decl(overloadsWithComputedNames.ts, 36, 24))
>uniqueSym : Symbol(uniqueSym, Decl(overloadsWithComputedNames.ts, 20, 13))
[uniqueSym](): void;
>[uniqueSym] : Symbol(I1[uniqueSym], Decl(overloadsWithComputedNames.ts, 35, 25), Decl(overloadsWithComputedNames.ts, 36, 24))
>uniqueSym : Symbol(uniqueSym, Decl(overloadsWithComputedNames.ts, 20, 13))
}
class C2 {
>C2 : Symbol(C2, Decl(overloadsWithComputedNames.ts, 38, 1))
[strUnion](): void; // should error
>[strUnion] : Symbol(C2[strUnion], Decl(overloadsWithComputedNames.ts, 40, 10))
>strUnion : Symbol(strUnion, Decl(overloadsWithComputedNames.ts, 24, 13))
[strUnion]() { }
>[strUnion] : Symbol(C2[strUnion], Decl(overloadsWithComputedNames.ts, 41, 23))
>strUnion : Symbol(strUnion, Decl(overloadsWithComputedNames.ts, 24, 13))
}
class I2 {
>I2 : Symbol(I2, Decl(overloadsWithComputedNames.ts, 43, 1))
[strUnion](): void; // should error
>[strUnion] : Symbol(I2[strUnion], Decl(overloadsWithComputedNames.ts, 45, 10))
>strUnion : Symbol(strUnion, Decl(overloadsWithComputedNames.ts, 24, 13))
[strUnion]() { }
>[strUnion] : Symbol(I2[strUnion], Decl(overloadsWithComputedNames.ts, 46, 23))
>strUnion : Symbol(strUnion, Decl(overloadsWithComputedNames.ts, 24, 13))
}
class C3 {
>C3 : Symbol(C3, Decl(overloadsWithComputedNames.ts, 48, 1))
[1](): void; // should error
>[1] : Symbol(C3[1], Decl(overloadsWithComputedNames.ts, 50, 10))
>1 : Symbol(C3[1], Decl(overloadsWithComputedNames.ts, 50, 10))
[2](): void;
>[2] : Symbol(C3[2], Decl(overloadsWithComputedNames.ts, 51, 16), Decl(overloadsWithComputedNames.ts, 52, 16))
>2 : Symbol(C3[2], Decl(overloadsWithComputedNames.ts, 51, 16), Decl(overloadsWithComputedNames.ts, 52, 16))
[2]() { }
>[2] : Symbol(C3[2], Decl(overloadsWithComputedNames.ts, 51, 16), Decl(overloadsWithComputedNames.ts, 52, 16))
>2 : Symbol(C3[2], Decl(overloadsWithComputedNames.ts, 51, 16), Decl(overloadsWithComputedNames.ts, 52, 16))
}
interface I3 {
>I3 : Symbol(I3, Decl(overloadsWithComputedNames.ts, 54, 1))
[1](): void;
>[1] : Symbol(I3[1], Decl(overloadsWithComputedNames.ts, 56, 14))
>1 : Symbol(I3[1], Decl(overloadsWithComputedNames.ts, 56, 14))
[2](): void;
>[2] : Symbol(I3[2], Decl(overloadsWithComputedNames.ts, 57, 16), Decl(overloadsWithComputedNames.ts, 58, 16))
>2 : Symbol(I3[2], Decl(overloadsWithComputedNames.ts, 57, 16), Decl(overloadsWithComputedNames.ts, 58, 16))
[2](): void;
>[2] : Symbol(I3[2], Decl(overloadsWithComputedNames.ts, 57, 16), Decl(overloadsWithComputedNames.ts, 58, 16))
>2 : Symbol(I3[2], Decl(overloadsWithComputedNames.ts, 57, 16), Decl(overloadsWithComputedNames.ts, 58, 16))
}
@@ -0,0 +1,162 @@
=== tests/cases/compiler/overloadsWithComputedNames.ts ===
// https://github.com/microsoft/TypeScript/issues/52329
class Person {
>Person : Person
["B"](a: number): string;
>["B"] : (a: number) => string
>"B" : "B"
>a : number
["A"](a: string|number): number | string {
>["A"] : (a: string | number) => number | string
>"A" : "A"
>a : string | number
return 0;
>0 : 0
}
}
let p = new Person();
>p : Person
>new Person() : Person
>Person : typeof Person
p.A(0)
>p.A(0) : string | number
>p.A : (a: string | number) => string | number
>p : Person
>A : (a: string | number) => string | number
>0 : 0
p.B(0)
>p.B(0) : string
>p.B : (a: number) => string
>p : Person
>B : (a: number) => string
>0 : 0
// https://github.com/microsoft/TypeScript/issues/17345
class C {
>C : C
["foo"](): void
>["foo"] : { (): void; (): number; }
>"foo" : "foo"
["bar"](): void;
>["bar"] : () => void
>"bar" : "bar"
["foo"]() {
>["foo"] : { (): void; (): number; }
>"foo" : "foo"
return 0;
>0 : 0
}
}
declare const uniqueSym: unique symbol;
>uniqueSym : unique symbol
declare const uniqueSym2: unique symbol;
>uniqueSym2 : unique symbol
declare const sym: symbol;
>sym : symbol
declare const strUnion: 'foo' | 'bar';
>strUnion : "foo" | "bar"
class C1 {
>C1 : C1
[sym](): void; // should error
>[sym] : () => void
>sym : symbol
[uniqueSym2](): void; // should error
>[uniqueSym2] : () => void
>uniqueSym2 : unique symbol
[uniqueSym](): void;
>[uniqueSym] : () => void
>uniqueSym : unique symbol
[uniqueSym]() { }
>[uniqueSym] : () => void
>uniqueSym : unique symbol
}
interface I1 {
[sym](): void; // should error
>[sym] : () => void
>sym : symbol
[uniqueSym2](): void;
>[uniqueSym2] : () => void
>uniqueSym2 : unique symbol
[uniqueSym](): void;
>[uniqueSym] : { (): void; (): void; }
>uniqueSym : unique symbol
[uniqueSym](): void;
>[uniqueSym] : { (): void; (): void; }
>uniqueSym : unique symbol
}
class C2 {
>C2 : C2
[strUnion](): void; // should error
>[strUnion] : () => void
>strUnion : "foo" | "bar"
[strUnion]() { }
>[strUnion] : () => void
>strUnion : "foo" | "bar"
}
class I2 {
>I2 : I2
[strUnion](): void; // should error
>[strUnion] : () => void
>strUnion : "foo" | "bar"
[strUnion]() { }
>[strUnion] : () => void
>strUnion : "foo" | "bar"
}
class C3 {
>C3 : C3
[1](): void; // should error
>[1] : () => void
>1 : 1
[2](): void;
>[2] : () => void
>2 : 2
[2]() { }
>[2] : () => void
>2 : 2
}
interface I3 {
[1](): void;
>[1] : () => void
>1 : 1
[2](): void;
>[2] : { (): void; (): void; }
>2 : 2
[2](): void;
>[2] : { (): void; (): void; }
>2 : 2
}
@@ -0,0 +1,61 @@
// https://github.com/microsoft/TypeScript/issues/52329
class Person {
["B"](a: number): string;
["A"](a: string|number): number | string {
return 0;
}
}
let p = new Person();
p.A(0)
p.B(0)
// https://github.com/microsoft/TypeScript/issues/17345
class C {
["foo"](): void
["bar"](): void;
["foo"]() {
return 0;
}
}
declare const uniqueSym: unique symbol;
declare const uniqueSym2: unique symbol;
declare const sym: symbol;
declare const strUnion: 'foo' | 'bar';
class C1 {
[sym](): void; // should error
[uniqueSym2](): void; // should error
[uniqueSym](): void;
[uniqueSym]() { }
}
interface I1 {
[sym](): void; // should error
[uniqueSym2](): void;
[uniqueSym](): void;
[uniqueSym](): void;
}
class C2 {
[strUnion](): void; // should error
[strUnion]() { }
}
class I2 {
[strUnion](): void; // should error
[strUnion]() { }
}
class C3 {
[1](): void; // should error
[2](): void;
[2]() { }
}
interface I3 {
[1](): void;
[2](): void;
[2](): void;
}