mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-04 00:45:37 -05:00
Fix interface extends clause
This commit is contained in:
@@ -1792,9 +1792,10 @@ namespace ts {
|
||||
return containerKind === SyntaxKind.InterfaceDeclaration || containerKind === SyntaxKind.TypeLiteral;
|
||||
}
|
||||
|
||||
export function isFirstIdentifierOfImplementsClause(node: Node) {
|
||||
return node.parent?.parent?.parent?.kind === SyntaxKind.HeritageClause
|
||||
&& (node.parent.parent.parent as HeritageClause).token === SyntaxKind.ImplementsKeyword;
|
||||
export function isFirstIdentifierOfNonEmittingHeritageClause(node: Node): boolean {
|
||||
// Number of parents to climb from identifier is 2 for `implements I`, 3 for `implements x.I`
|
||||
const heritageClause = tryCast(node.parent.parent, isHeritageClause) ?? tryCast(node.parent.parent.parent, isHeritageClause);
|
||||
return heritageClause?.token === SyntaxKind.ImplementsKeyword || heritageClause?.parent.kind === SyntaxKind.InterfaceDeclaration;
|
||||
}
|
||||
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration & { moduleReference: ExternalModuleReference } {
|
||||
@@ -6143,7 +6144,7 @@ namespace ts {
|
||||
export function isValidTypeOnlyAliasUseSite(useSite: Node): boolean {
|
||||
return !!(useSite.flags & NodeFlags.Ambient)
|
||||
|| isPartOfTypeQuery(useSite)
|
||||
|| isFirstIdentifierOfImplementsClause(useSite)
|
||||
|| isFirstIdentifierOfNonEmittingHeritageClause(useSite)
|
||||
|| isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
|
||||
|| !isExpressionNode(useSite);
|
||||
}
|
||||
|
||||
30
tests/baselines/reference/extendsClause.errors.txt
Normal file
30
tests/baselines/reference/extendsClause.errors.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
tests/cases/conformance/externalModules/typeOnly/index.ts(9,17): error TS1361: 'C' cannot be used as a value because it was imported using 'import type'.
|
||||
tests/cases/conformance/externalModules/typeOnly/index.ts(10,17): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/externalModules/typeOnly/types.ts (0 errors) ====
|
||||
export interface I {}
|
||||
export class C {}
|
||||
|
||||
==== tests/cases/conformance/externalModules/typeOnly/ns.ts (0 errors) ====
|
||||
import type * as types from './types';
|
||||
export { types };
|
||||
|
||||
==== tests/cases/conformance/externalModules/typeOnly/index.ts (2 errors) ====
|
||||
import { types } from './ns';
|
||||
import type { C, I } from './types';
|
||||
|
||||
interface Q extends C {}
|
||||
interface R extends I {}
|
||||
interface S extends types.C {}
|
||||
interface T extends types.I {}
|
||||
|
||||
class U extends C {} // Error
|
||||
~
|
||||
!!! error TS1361: 'C' cannot be used as a value because it was imported using 'import type'.
|
||||
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/index.ts:2:15: 'C' was imported here.
|
||||
class V extends types.C {} // Error
|
||||
~~~~~
|
||||
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
|
||||
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/ns.ts:1:13: 'types' was imported here.
|
||||
|
||||
65
tests/baselines/reference/extendsClause.js
Normal file
65
tests/baselines/reference/extendsClause.js
Normal file
@@ -0,0 +1,65 @@
|
||||
//// [tests/cases/conformance/externalModules/typeOnly/extendsClause.ts] ////
|
||||
|
||||
//// [types.ts]
|
||||
export interface I {}
|
||||
export class C {}
|
||||
|
||||
//// [ns.ts]
|
||||
import type * as types from './types';
|
||||
export { types };
|
||||
|
||||
//// [index.ts]
|
||||
import { types } from './ns';
|
||||
import type { C, I } from './types';
|
||||
|
||||
interface Q extends C {}
|
||||
interface R extends I {}
|
||||
interface S extends types.C {}
|
||||
interface T extends types.I {}
|
||||
|
||||
class U extends C {} // Error
|
||||
class V extends types.C {} // Error
|
||||
|
||||
|
||||
//// [types.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
exports.C = C;
|
||||
//// [ns.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
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 __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var U = /** @class */ (function (_super) {
|
||||
__extends(U, _super);
|
||||
function U() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return U;
|
||||
}(C)); // Error
|
||||
var V = /** @class */ (function (_super) {
|
||||
__extends(V, _super);
|
||||
function V() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return V;
|
||||
}(types.C)); // Error
|
||||
52
tests/baselines/reference/extendsClause.symbols
Normal file
52
tests/baselines/reference/extendsClause.symbols
Normal file
@@ -0,0 +1,52 @@
|
||||
=== tests/cases/conformance/externalModules/typeOnly/types.ts ===
|
||||
export interface I {}
|
||||
>I : Symbol(I, Decl(types.ts, 0, 0))
|
||||
|
||||
export class C {}
|
||||
>C : Symbol(C, Decl(types.ts, 0, 21))
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/ns.ts ===
|
||||
import type * as types from './types';
|
||||
>types : Symbol(types, Decl(ns.ts, 0, 11))
|
||||
|
||||
export { types };
|
||||
>types : Symbol(types, Decl(ns.ts, 1, 8))
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/index.ts ===
|
||||
import { types } from './ns';
|
||||
>types : Symbol(types, Decl(index.ts, 0, 8))
|
||||
|
||||
import type { C, I } from './types';
|
||||
>C : Symbol(C, Decl(index.ts, 1, 13))
|
||||
>I : Symbol(I, Decl(index.ts, 1, 16))
|
||||
|
||||
interface Q extends C {}
|
||||
>Q : Symbol(Q, Decl(index.ts, 1, 36))
|
||||
>C : Symbol(C, Decl(index.ts, 1, 13))
|
||||
|
||||
interface R extends I {}
|
||||
>R : Symbol(R, Decl(index.ts, 3, 24))
|
||||
>I : Symbol(I, Decl(index.ts, 1, 16))
|
||||
|
||||
interface S extends types.C {}
|
||||
>S : Symbol(S, Decl(index.ts, 4, 24))
|
||||
>types.C : Symbol(types.C, Decl(types.ts, 0, 21))
|
||||
>types : Symbol(types, Decl(index.ts, 0, 8))
|
||||
>C : Symbol(types.C, Decl(types.ts, 0, 21))
|
||||
|
||||
interface T extends types.I {}
|
||||
>T : Symbol(T, Decl(index.ts, 5, 30))
|
||||
>types.I : Symbol(types.I, Decl(types.ts, 0, 0))
|
||||
>types : Symbol(types, Decl(index.ts, 0, 8))
|
||||
>I : Symbol(types.I, Decl(types.ts, 0, 0))
|
||||
|
||||
class U extends C {} // Error
|
||||
>U : Symbol(U, Decl(index.ts, 6, 30))
|
||||
>C : Symbol(C, Decl(index.ts, 1, 13))
|
||||
|
||||
class V extends types.C {} // Error
|
||||
>V : Symbol(V, Decl(index.ts, 8, 20))
|
||||
>types.C : Symbol(types.C, Decl(types.ts, 0, 21))
|
||||
>types : Symbol(types, Decl(index.ts, 0, 8))
|
||||
>C : Symbol(types.C, Decl(types.ts, 0, 21))
|
||||
|
||||
38
tests/baselines/reference/extendsClause.types
Normal file
38
tests/baselines/reference/extendsClause.types
Normal file
@@ -0,0 +1,38 @@
|
||||
=== tests/cases/conformance/externalModules/typeOnly/types.ts ===
|
||||
export interface I {}
|
||||
export class C {}
|
||||
>C : C
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/ns.ts ===
|
||||
import type * as types from './types';
|
||||
>types : typeof types
|
||||
|
||||
export { types };
|
||||
>types : typeof types
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/index.ts ===
|
||||
import { types } from './ns';
|
||||
>types : typeof types
|
||||
|
||||
import type { C, I } from './types';
|
||||
>C : types.C
|
||||
>I : types.I
|
||||
|
||||
interface Q extends C {}
|
||||
interface R extends I {}
|
||||
interface S extends types.C {}
|
||||
>types : typeof types
|
||||
|
||||
interface T extends types.I {}
|
||||
>types : typeof types
|
||||
|
||||
class U extends C {} // Error
|
||||
>U : U
|
||||
>C : types.C
|
||||
|
||||
class V extends types.C {} // Error
|
||||
>V : V
|
||||
>types.C : types.C
|
||||
>types : typeof types
|
||||
>C : typeof types.C
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// @Filename: types.ts
|
||||
export interface I {}
|
||||
export class C {}
|
||||
|
||||
// @Filename: ns.ts
|
||||
import type * as types from './types';
|
||||
export { types };
|
||||
|
||||
// @Filename: index.ts
|
||||
import { types } from './ns';
|
||||
import type { C, I } from './types';
|
||||
|
||||
interface Q extends C {}
|
||||
interface R extends I {}
|
||||
interface S extends types.C {}
|
||||
interface T extends types.I {}
|
||||
|
||||
class U extends C {} // Error
|
||||
class V extends types.C {} // Error
|
||||
Reference in New Issue
Block a user