mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 20:51:43 -06:00
feat(47595): allow using private fields in type queries (#47696)
This commit is contained in:
parent
3b95404f59
commit
063eaa70e6
@ -875,7 +875,7 @@ namespace ts {
|
||||
initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true);
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false);
|
||||
const isInvalid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length;
|
||||
clearState();
|
||||
return isInvalid ? entityName : undefined;
|
||||
@ -2719,7 +2719,7 @@ namespace ts {
|
||||
return createMissingList<T>();
|
||||
}
|
||||
|
||||
function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {
|
||||
function parseEntityName(allowReservedWords: boolean, allowPrivateIdentifiers: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {
|
||||
const pos = getNodePos();
|
||||
let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
|
||||
let dotPos = getNodePos();
|
||||
@ -2733,7 +2733,7 @@ namespace ts {
|
||||
entity = finishNode(
|
||||
factory.createQualifiedName(
|
||||
entity,
|
||||
parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier
|
||||
parseRightSideOfDot(allowReservedWords, allowPrivateIdentifiers) as Identifier
|
||||
),
|
||||
pos
|
||||
);
|
||||
@ -2918,7 +2918,7 @@ namespace ts {
|
||||
// TYPES
|
||||
|
||||
function parseEntityNameOfTypeReference() {
|
||||
return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected);
|
||||
return parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false, Diagnostics.Type_expected);
|
||||
}
|
||||
|
||||
function parseTypeArgumentsOfTypeReference() {
|
||||
@ -3078,7 +3078,7 @@ namespace ts {
|
||||
function parseTypeQuery(): TypeQueryNode {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.TypeOfKeyword);
|
||||
return finishNode(factory.createTypeQueryNode(parseEntityName(/*allowReservedWords*/ true)), pos);
|
||||
return finishNode(factory.createTypeQueryNode(parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ true)), pos);
|
||||
}
|
||||
|
||||
function parseTypeParameter(): TypeParameterDeclaration {
|
||||
@ -7351,7 +7351,7 @@ namespace ts {
|
||||
function parseModuleReference() {
|
||||
return isExternalModuleReference()
|
||||
? parseExternalModuleReference()
|
||||
: parseEntityName(/*allowReservedWords*/ false);
|
||||
: parseEntityName(/*allowReservedWords*/ false, /*allowPrivateIdentifiers*/ false);
|
||||
}
|
||||
|
||||
function parseExternalModuleReference() {
|
||||
@ -7659,7 +7659,7 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasBrace = parseOptional(SyntaxKind.OpenBraceToken);
|
||||
const p2 = getNodePos();
|
||||
let entityName: EntityName | JSDocMemberName = parseEntityName(/* allowReservedWords*/ false);
|
||||
let entityName: EntityName | JSDocMemberName = parseEntityName(/* allowReservedWords*/ false, /*allowPrivateIdentifiers*/ false);
|
||||
while (token() === SyntaxKind.PrivateIdentifier) {
|
||||
reScanHashToken(); // rescan #id as # id
|
||||
nextTokenJSDoc(); // then skip the #
|
||||
@ -8122,7 +8122,7 @@ namespace ts {
|
||||
// parseEntityName logs an error for non-identifier, so create a MissingNode ourselves to avoid the error
|
||||
const p2 = getNodePos();
|
||||
let name: EntityName | JSDocMemberName | undefined = tokenIsIdentifierOrKeyword(token())
|
||||
? parseEntityName(/*allowReservedWords*/ true)
|
||||
? parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false)
|
||||
: undefined;
|
||||
if (name) {
|
||||
while (token() === SyntaxKind.PrivateIdentifier) {
|
||||
|
||||
21
tests/baselines/reference/privateNameInTypeQuery.errors.txt
Normal file
21
tests/baselines/reference/privateNameInTypeQuery.errors.txt
Normal file
@ -0,0 +1,21 @@
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameInTypeQuery.ts(6,15): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameInTypeQuery.ts(11,19): error TS18013: Property '#a' is not accessible outside class 'C' because it has a private identifier.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/members/privateNames/privateNameInTypeQuery.ts (2 errors) ====
|
||||
class C {
|
||||
#a = 'a';
|
||||
|
||||
constructor() {
|
||||
const a: typeof this.#a = ''; // Ok
|
||||
const b: typeof this.#a = 1; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
}
|
||||
}
|
||||
|
||||
const c = new C();
|
||||
const a: typeof c.#a = '';
|
||||
~~
|
||||
!!! error TS18013: Property '#a' is not accessible outside class 'C' because it has a private identifier.
|
||||
|
||||
25
tests/baselines/reference/privateNameInTypeQuery.js
Normal file
25
tests/baselines/reference/privateNameInTypeQuery.js
Normal file
@ -0,0 +1,25 @@
|
||||
//// [privateNameInTypeQuery.ts]
|
||||
class C {
|
||||
#a = 'a';
|
||||
|
||||
constructor() {
|
||||
const a: typeof this.#a = ''; // Ok
|
||||
const b: typeof this.#a = 1; // Error
|
||||
}
|
||||
}
|
||||
|
||||
const c = new C();
|
||||
const a: typeof c.#a = '';
|
||||
|
||||
|
||||
//// [privateNameInTypeQuery.js]
|
||||
"use strict";
|
||||
class C {
|
||||
#a = 'a';
|
||||
constructor() {
|
||||
const a = ''; // Ok
|
||||
const b = 1; // Error
|
||||
}
|
||||
}
|
||||
const c = new C();
|
||||
const a = '';
|
||||
28
tests/baselines/reference/privateNameInTypeQuery.symbols
Normal file
28
tests/baselines/reference/privateNameInTypeQuery.symbols
Normal file
@ -0,0 +1,28 @@
|
||||
=== tests/cases/conformance/classes/members/privateNames/privateNameInTypeQuery.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(privateNameInTypeQuery.ts, 0, 0))
|
||||
|
||||
#a = 'a';
|
||||
>#a : Symbol(C.#a, Decl(privateNameInTypeQuery.ts, 0, 9))
|
||||
|
||||
constructor() {
|
||||
const a: typeof this.#a = ''; // Ok
|
||||
>a : Symbol(a, Decl(privateNameInTypeQuery.ts, 4, 13))
|
||||
>this.#a : Symbol(C.#a, Decl(privateNameInTypeQuery.ts, 0, 9))
|
||||
>this : Symbol(C, Decl(privateNameInTypeQuery.ts, 0, 0))
|
||||
|
||||
const b: typeof this.#a = 1; // Error
|
||||
>b : Symbol(b, Decl(privateNameInTypeQuery.ts, 5, 13))
|
||||
>this.#a : Symbol(C.#a, Decl(privateNameInTypeQuery.ts, 0, 9))
|
||||
>this : Symbol(C, Decl(privateNameInTypeQuery.ts, 0, 0))
|
||||
}
|
||||
}
|
||||
|
||||
const c = new C();
|
||||
>c : Symbol(c, Decl(privateNameInTypeQuery.ts, 9, 5))
|
||||
>C : Symbol(C, Decl(privateNameInTypeQuery.ts, 0, 0))
|
||||
|
||||
const a: typeof c.#a = '';
|
||||
>a : Symbol(a, Decl(privateNameInTypeQuery.ts, 10, 5))
|
||||
>c : Symbol(c, Decl(privateNameInTypeQuery.ts, 9, 5))
|
||||
|
||||
34
tests/baselines/reference/privateNameInTypeQuery.types
Normal file
34
tests/baselines/reference/privateNameInTypeQuery.types
Normal file
@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/classes/members/privateNames/privateNameInTypeQuery.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
#a = 'a';
|
||||
>#a : string
|
||||
>'a' : "a"
|
||||
|
||||
constructor() {
|
||||
const a: typeof this.#a = ''; // Ok
|
||||
>a : string
|
||||
>this.#a : string
|
||||
>this : this
|
||||
>'' : ""
|
||||
|
||||
const b: typeof this.#a = 1; // Error
|
||||
>b : string
|
||||
>this.#a : string
|
||||
>this : this
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
const c = new C();
|
||||
>c : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
|
||||
const a: typeof c.#a = '';
|
||||
>a : any
|
||||
>c.#a : any
|
||||
>c : C
|
||||
>'' : ""
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
// @strict: true
|
||||
// @target: esnext
|
||||
|
||||
class C {
|
||||
#a = 'a';
|
||||
|
||||
constructor() {
|
||||
const a: typeof this.#a = ''; // Ok
|
||||
const b: typeof this.#a = 1; // Error
|
||||
}
|
||||
}
|
||||
|
||||
const c = new C();
|
||||
const a: typeof c.#a = '';
|
||||
Loading…
x
Reference in New Issue
Block a user