mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Fix #9636: Report unused type paramters only on last declaration
This commit is contained in:
parent
9ef65cf3af
commit
290caad402
@ -13274,7 +13274,7 @@ namespace ts {
|
||||
checkAsyncFunctionReturnType(<FunctionLikeDeclaration>node);
|
||||
}
|
||||
}
|
||||
if (!(<FunctionDeclaration>node).body) {
|
||||
if (noUnusedIdentifiers && !(<FunctionDeclaration>node).body) {
|
||||
checkUnusedTypeParameters(node);
|
||||
}
|
||||
}
|
||||
@ -14609,8 +14609,15 @@ namespace ts {
|
||||
function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration) {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
if (node.typeParameters) {
|
||||
// Only report errors on the last declaration for the type parameter container;
|
||||
// this ensures that all uses have been accounted for.
|
||||
const symbol = node.symbol && getMergedSymbol(node.symbol);
|
||||
const lastDeclaration = symbol && symbol.declarations && lastOrUndefined(symbol.declarations);
|
||||
if (lastDeclaration !== node) {
|
||||
return;
|
||||
}
|
||||
for (const typeParameter of node.typeParameters) {
|
||||
if (!typeParameter.symbol.isReferenced) {
|
||||
if (!getMergedSymbol(typeParameter.symbol).isReferenced) {
|
||||
error(typeParameter.name, Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name);
|
||||
}
|
||||
}
|
||||
@ -16119,7 +16126,7 @@ namespace ts {
|
||||
|
||||
if (produceDiagnostics) {
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
checkUnusedTypeParameters(node);
|
||||
registerForUnusedIdentifiersCheck(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
16
tests/baselines/reference/unusedTypeParameters6.js
Normal file
16
tests/baselines/reference/unusedTypeParameters6.js
Normal file
@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/unusedTypeParameters6.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
|
||||
class C<T> { }
|
||||
|
||||
//// [b.ts]
|
||||
interface C<T> { a: T; }
|
||||
|
||||
//// [a.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
//// [b.js]
|
||||
13
tests/baselines/reference/unusedTypeParameters6.symbols
Normal file
13
tests/baselines/reference/unusedTypeParameters6.symbols
Normal file
@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class C<T> { }
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(b.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
interface C<T> { a: T; }
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(b.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
>a : Symbol(C.a, Decl(b.ts, 0, 16))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
|
||||
13
tests/baselines/reference/unusedTypeParameters6.types
Normal file
13
tests/baselines/reference/unusedTypeParameters6.types
Normal file
@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class C<T> { }
|
||||
>C : C<T>
|
||||
>T : T
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
interface C<T> { a: T; }
|
||||
>C : C<T>
|
||||
>T : T
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
16
tests/baselines/reference/unusedTypeParameters7.js
Normal file
16
tests/baselines/reference/unusedTypeParameters7.js
Normal file
@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/unusedTypeParameters7.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
|
||||
class C<T> { a: T; }
|
||||
|
||||
//// [b.ts]
|
||||
interface C<T> { }
|
||||
|
||||
//// [a.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
//// [b.js]
|
||||
13
tests/baselines/reference/unusedTypeParameters7.symbols
Normal file
13
tests/baselines/reference/unusedTypeParameters7.symbols
Normal file
@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class C<T> { a: T; }
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(b.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
>a : Symbol(C.a, Decl(a.ts, 1, 12))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
interface C<T> { }
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(b.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(a.ts, 1, 8), Decl(b.ts, 0, 12))
|
||||
|
||||
13
tests/baselines/reference/unusedTypeParameters7.types
Normal file
13
tests/baselines/reference/unusedTypeParameters7.types
Normal file
@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class C<T> { a: T; }
|
||||
>C : C<T>
|
||||
>T : T
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
interface C<T> { }
|
||||
>C : C<T>
|
||||
>T : T
|
||||
|
||||
11
tests/baselines/reference/unusedTypeParameters8.errors.txt
Normal file
11
tests/baselines/reference/unusedTypeParameters8.errors.txt
Normal file
@ -0,0 +1,11 @@
|
||||
tests/cases/compiler/b.ts(1,13): error TS6133: 'T' is declared but never used.
|
||||
|
||||
|
||||
==== tests/cases/compiler/a.ts (0 errors) ====
|
||||
|
||||
class C<T> { }
|
||||
|
||||
==== tests/cases/compiler/b.ts (1 errors) ====
|
||||
interface C<T> { }
|
||||
~
|
||||
!!! error TS6133: 'T' is declared but never used.
|
||||
16
tests/baselines/reference/unusedTypeParameters8.js
Normal file
16
tests/baselines/reference/unusedTypeParameters8.js
Normal file
@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/unusedTypeParameters8.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
|
||||
class C<T> { }
|
||||
|
||||
//// [b.ts]
|
||||
interface C<T> { }
|
||||
|
||||
//// [a.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
//// [b.js]
|
||||
30
tests/baselines/reference/unusedTypeParameters9.js
Normal file
30
tests/baselines/reference/unusedTypeParameters9.js
Normal file
@ -0,0 +1,30 @@
|
||||
//// [unusedTypeParameters9.ts]
|
||||
|
||||
// clas + interface
|
||||
class C1<T> { }
|
||||
interface C1<T> { a: T; }
|
||||
|
||||
// interface + class
|
||||
class C2<T> { a: T; }
|
||||
interface C2<T> { }
|
||||
|
||||
// interfaces
|
||||
interface C3<T> { a(c: (p: T) => void): void; }
|
||||
interface C3<T> { b: string; }
|
||||
interface C3<T> { c: number; }
|
||||
interface C3<T> { d: boolean; }
|
||||
interface C3<T> { e: any; }
|
||||
|
||||
//// [unusedTypeParameters9.js]
|
||||
// clas + interface
|
||||
var C1 = (function () {
|
||||
function C1() {
|
||||
}
|
||||
return C1;
|
||||
}());
|
||||
// interface + class
|
||||
var C2 = (function () {
|
||||
function C2() {
|
||||
}
|
||||
return C2;
|
||||
}());
|
||||
53
tests/baselines/reference/unusedTypeParameters9.symbols
Normal file
53
tests/baselines/reference/unusedTypeParameters9.symbols
Normal file
@ -0,0 +1,53 @@
|
||||
=== tests/cases/compiler/unusedTypeParameters9.ts ===
|
||||
|
||||
// clas + interface
|
||||
class C1<T> { }
|
||||
>C1 : Symbol(C1, Decl(unusedTypeParameters9.ts, 0, 0), Decl(unusedTypeParameters9.ts, 2, 15))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 2, 9), Decl(unusedTypeParameters9.ts, 3, 13))
|
||||
|
||||
interface C1<T> { a: T; }
|
||||
>C1 : Symbol(C1, Decl(unusedTypeParameters9.ts, 0, 0), Decl(unusedTypeParameters9.ts, 2, 15))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 2, 9), Decl(unusedTypeParameters9.ts, 3, 13))
|
||||
>a : Symbol(C1.a, Decl(unusedTypeParameters9.ts, 3, 17))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 2, 9), Decl(unusedTypeParameters9.ts, 3, 13))
|
||||
|
||||
// interface + class
|
||||
class C2<T> { a: T; }
|
||||
>C2 : Symbol(C2, Decl(unusedTypeParameters9.ts, 3, 25), Decl(unusedTypeParameters9.ts, 6, 21))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 6, 9), Decl(unusedTypeParameters9.ts, 7, 13))
|
||||
>a : Symbol(C2.a, Decl(unusedTypeParameters9.ts, 6, 13))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 6, 9), Decl(unusedTypeParameters9.ts, 7, 13))
|
||||
|
||||
interface C2<T> { }
|
||||
>C2 : Symbol(C2, Decl(unusedTypeParameters9.ts, 3, 25), Decl(unusedTypeParameters9.ts, 6, 21))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 6, 9), Decl(unusedTypeParameters9.ts, 7, 13))
|
||||
|
||||
// interfaces
|
||||
interface C3<T> { a(c: (p: T) => void): void; }
|
||||
>C3 : Symbol(C3, Decl(unusedTypeParameters9.ts, 7, 19), Decl(unusedTypeParameters9.ts, 10, 47), Decl(unusedTypeParameters9.ts, 11, 30), Decl(unusedTypeParameters9.ts, 12, 30), Decl(unusedTypeParameters9.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
>a : Symbol(C3.a, Decl(unusedTypeParameters9.ts, 10, 17))
|
||||
>c : Symbol(c, Decl(unusedTypeParameters9.ts, 10, 20))
|
||||
>p : Symbol(p, Decl(unusedTypeParameters9.ts, 10, 24))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
|
||||
interface C3<T> { b: string; }
|
||||
>C3 : Symbol(C3, Decl(unusedTypeParameters9.ts, 7, 19), Decl(unusedTypeParameters9.ts, 10, 47), Decl(unusedTypeParameters9.ts, 11, 30), Decl(unusedTypeParameters9.ts, 12, 30), Decl(unusedTypeParameters9.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
>b : Symbol(C3.b, Decl(unusedTypeParameters9.ts, 11, 17))
|
||||
|
||||
interface C3<T> { c: number; }
|
||||
>C3 : Symbol(C3, Decl(unusedTypeParameters9.ts, 7, 19), Decl(unusedTypeParameters9.ts, 10, 47), Decl(unusedTypeParameters9.ts, 11, 30), Decl(unusedTypeParameters9.ts, 12, 30), Decl(unusedTypeParameters9.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
>c : Symbol(C3.c, Decl(unusedTypeParameters9.ts, 12, 17))
|
||||
|
||||
interface C3<T> { d: boolean; }
|
||||
>C3 : Symbol(C3, Decl(unusedTypeParameters9.ts, 7, 19), Decl(unusedTypeParameters9.ts, 10, 47), Decl(unusedTypeParameters9.ts, 11, 30), Decl(unusedTypeParameters9.ts, 12, 30), Decl(unusedTypeParameters9.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
>d : Symbol(C3.d, Decl(unusedTypeParameters9.ts, 13, 17))
|
||||
|
||||
interface C3<T> { e: any; }
|
||||
>C3 : Symbol(C3, Decl(unusedTypeParameters9.ts, 7, 19), Decl(unusedTypeParameters9.ts, 10, 47), Decl(unusedTypeParameters9.ts, 11, 30), Decl(unusedTypeParameters9.ts, 12, 30), Decl(unusedTypeParameters9.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(unusedTypeParameters9.ts, 10, 13), Decl(unusedTypeParameters9.ts, 11, 13), Decl(unusedTypeParameters9.ts, 12, 13), Decl(unusedTypeParameters9.ts, 13, 13), Decl(unusedTypeParameters9.ts, 14, 13))
|
||||
>e : Symbol(C3.e, Decl(unusedTypeParameters9.ts, 14, 17))
|
||||
|
||||
53
tests/baselines/reference/unusedTypeParameters9.types
Normal file
53
tests/baselines/reference/unusedTypeParameters9.types
Normal file
@ -0,0 +1,53 @@
|
||||
=== tests/cases/compiler/unusedTypeParameters9.ts ===
|
||||
|
||||
// clas + interface
|
||||
class C1<T> { }
|
||||
>C1 : C1<T>
|
||||
>T : T
|
||||
|
||||
interface C1<T> { a: T; }
|
||||
>C1 : C1<T>
|
||||
>T : T
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
// interface + class
|
||||
class C2<T> { a: T; }
|
||||
>C2 : C2<T>
|
||||
>T : T
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
interface C2<T> { }
|
||||
>C2 : C2<T>
|
||||
>T : T
|
||||
|
||||
// interfaces
|
||||
interface C3<T> { a(c: (p: T) => void): void; }
|
||||
>C3 : C3<T>
|
||||
>T : T
|
||||
>a : (c: (p: T) => void) => void
|
||||
>c : (p: T) => void
|
||||
>p : T
|
||||
>T : T
|
||||
|
||||
interface C3<T> { b: string; }
|
||||
>C3 : C3<T>
|
||||
>T : T
|
||||
>b : string
|
||||
|
||||
interface C3<T> { c: number; }
|
||||
>C3 : C3<T>
|
||||
>T : T
|
||||
>c : number
|
||||
|
||||
interface C3<T> { d: boolean; }
|
||||
>C3 : C3<T>
|
||||
>T : T
|
||||
>d : boolean
|
||||
|
||||
interface C3<T> { e: any; }
|
||||
>C3 : C3<T>
|
||||
>T : T
|
||||
>e : any
|
||||
|
||||
8
tests/cases/compiler/unusedTypeParameters6.ts
Normal file
8
tests/cases/compiler/unusedTypeParameters6.ts
Normal file
@ -0,0 +1,8 @@
|
||||
//@noUnusedLocals:true
|
||||
//@noUnusedParameters:true
|
||||
|
||||
// @fileName: a.ts
|
||||
class C<T> { }
|
||||
|
||||
// @fileName: b.ts
|
||||
interface C<T> { a: T; }
|
||||
8
tests/cases/compiler/unusedTypeParameters7.ts
Normal file
8
tests/cases/compiler/unusedTypeParameters7.ts
Normal file
@ -0,0 +1,8 @@
|
||||
//@noUnusedLocals:true
|
||||
//@noUnusedParameters:true
|
||||
|
||||
// @fileName: a.ts
|
||||
class C<T> { a: T; }
|
||||
|
||||
// @fileName: b.ts
|
||||
interface C<T> { }
|
||||
8
tests/cases/compiler/unusedTypeParameters8.ts
Normal file
8
tests/cases/compiler/unusedTypeParameters8.ts
Normal file
@ -0,0 +1,8 @@
|
||||
//@noUnusedLocals:true
|
||||
//@noUnusedParameters:true
|
||||
|
||||
// @fileName: a.ts
|
||||
class C<T> { }
|
||||
|
||||
// @fileName: b.ts
|
||||
interface C<T> { }
|
||||
17
tests/cases/compiler/unusedTypeParameters9.ts
Normal file
17
tests/cases/compiler/unusedTypeParameters9.ts
Normal file
@ -0,0 +1,17 @@
|
||||
//@noUnusedLocals:true
|
||||
//@noUnusedParameters:true
|
||||
|
||||
// clas + interface
|
||||
class C1<T> { }
|
||||
interface C1<T> { a: T; }
|
||||
|
||||
// interface + class
|
||||
class C2<T> { a: T; }
|
||||
interface C2<T> { }
|
||||
|
||||
// interfaces
|
||||
interface C3<T> { a(c: (p: T) => void): void; }
|
||||
interface C3<T> { b: string; }
|
||||
interface C3<T> { c: number; }
|
||||
interface C3<T> { d: boolean; }
|
||||
interface C3<T> { e: any; }
|
||||
Loading…
x
Reference in New Issue
Block a user