Skip to content

Commit f0ba16c

Browse files
mattmccutchenmhegazy
authored andcommitted
Unused type parameters should be checked by --noUnusedParameters, not (#21167)
--noUnusedLocals. Fixes #20568.
1 parent 9677b06 commit f0ba16c

25 files changed

+283
-19
lines changed

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -20967,7 +20967,7 @@ namespace ts {
2096720967
error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local));
2096820968
}
2096920969
}
20970-
else if (compilerOptions.noUnusedLocals) {
20970+
else if (local.flags & SymbolFlags.TypeParameter ? compilerOptions.noUnusedParameters : compilerOptions.noUnusedLocals) {
2097120971
forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local)));
2097220972
}
2097320973
}
@@ -21042,7 +21042,7 @@ namespace ts {
2104221042
}
2104321043

2104421044
function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) {
21045-
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
21045+
if (compilerOptions.noUnusedParameters && !(node.flags & NodeFlags.Ambient)) {
2104621046
if (node.typeParameters) {
2104721047
// Only report errors on the last declaration for the type parameter container;
2104821048
// this ensures that all uses have been accounted for.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(1,12): error TS6133: 'T' is declared but its value is never read.
2+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(3,8): error TS6133: 'T' is declared but its value is never read.
3+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(5,13): error TS6133: 'T' is declared but its value is never read.
4+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(7,9): error TS6133: 'T' is declared but its value is never read.
5+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(8,14): error TS6133: 'V' is declared but its value is never read.
6+
tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts(11,10): error TS6133: 'T' is declared but its value is never read.
7+
8+
9+
==== tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts (6 errors) ====
10+
function f<T>() { }
11+
~
12+
!!! error TS6133: 'T' is declared but its value is never read.
13+
14+
type T<T> = { };
15+
~
16+
!!! error TS6133: 'T' is declared but its value is never read.
17+
18+
interface I<T> { };
19+
~
20+
!!! error TS6133: 'T' is declared but its value is never read.
21+
22+
class C<T> {
23+
~
24+
!!! error TS6133: 'T' is declared but its value is never read.
25+
public m<V>() { }
26+
~
27+
!!! error TS6133: 'V' is declared but its value is never read.
28+
};
29+
30+
let l = <T>() => { };
31+
~
32+
!!! error TS6133: 'T' is declared but its value is never read.
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [unusedTypeParametersCheckedByNoUnusedParameters.ts]
2+
function f<T>() { }
3+
4+
type T<T> = { };
5+
6+
interface I<T> { };
7+
8+
class C<T> {
9+
public m<V>() { }
10+
};
11+
12+
let l = <T>() => { };
13+
14+
15+
//// [unusedTypeParametersCheckedByNoUnusedParameters.js]
16+
function f() { }
17+
;
18+
var C = /** @class */ (function () {
19+
function C() {
20+
}
21+
C.prototype.m = function () { };
22+
return C;
23+
}());
24+
;
25+
var l = function () { };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts ===
2+
function f<T>() { }
3+
>f : Symbol(f, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 0, 0))
4+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 0, 11))
5+
6+
type T<T> = { };
7+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 0, 19))
8+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 2, 7))
9+
10+
interface I<T> { };
11+
>I : Symbol(I, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 2, 16))
12+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 4, 12))
13+
14+
class C<T> {
15+
>C : Symbol(C, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 4, 19))
16+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 6, 8))
17+
18+
public m<V>() { }
19+
>m : Symbol(C.m, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 6, 12))
20+
>V : Symbol(V, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 7, 13))
21+
22+
};
23+
24+
let l = <T>() => { };
25+
>l : Symbol(l, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 10, 3))
26+
>T : Symbol(T, Decl(unusedTypeParametersCheckedByNoUnusedParameters.ts, 10, 9))
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/unusedTypeParametersCheckedByNoUnusedParameters.ts ===
2+
function f<T>() { }
3+
>f : <T>() => void
4+
>T : T
5+
6+
type T<T> = { };
7+
>T : {}
8+
>T : T
9+
10+
interface I<T> { };
11+
>I : I<T>
12+
>T : T
13+
14+
class C<T> {
15+
>C : C<T>
16+
>T : T
17+
18+
public m<V>() { }
19+
>m : <V>() => void
20+
>V : V
21+
22+
};
23+
24+
let l = <T>() => { };
25+
>l : <T>() => void
26+
><T>() => { } : <T>() => void
27+
>T : T
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [unusedTypeParametersNotCheckedByNoUnusedLocals.ts]
2+
function f<T>() { }
3+
4+
type T<T> = { };
5+
6+
interface I<T> { };
7+
8+
class C<T> {
9+
public m<V>() { }
10+
};
11+
12+
let l = <T>() => { };
13+
14+
15+
//// [unusedTypeParametersNotCheckedByNoUnusedLocals.js]
16+
function f() { }
17+
;
18+
var C = /** @class */ (function () {
19+
function C() {
20+
}
21+
C.prototype.m = function () { };
22+
return C;
23+
}());
24+
;
25+
var l = function () { };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/unusedTypeParametersNotCheckedByNoUnusedLocals.ts ===
2+
function f<T>() { }
3+
>f : Symbol(f, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 0, 0))
4+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 0, 11))
5+
6+
type T<T> = { };
7+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 0, 19))
8+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 2, 7))
9+
10+
interface I<T> { };
11+
>I : Symbol(I, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 2, 16))
12+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 4, 12))
13+
14+
class C<T> {
15+
>C : Symbol(C, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 4, 19))
16+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 6, 8))
17+
18+
public m<V>() { }
19+
>m : Symbol(C.m, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 6, 12))
20+
>V : Symbol(V, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 7, 13))
21+
22+
};
23+
24+
let l = <T>() => { };
25+
>l : Symbol(l, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 10, 3))
26+
>T : Symbol(T, Decl(unusedTypeParametersNotCheckedByNoUnusedLocals.ts, 10, 9))
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/unusedTypeParametersNotCheckedByNoUnusedLocals.ts ===
2+
function f<T>() { }
3+
>f : <T>() => void
4+
>T : T
5+
6+
type T<T> = { };
7+
>T : {}
8+
>T : T
9+
10+
interface I<T> { };
11+
>I : I<T>
12+
>T : T
13+
14+
class C<T> {
15+
>C : C<T>
16+
>T : T
17+
18+
public m<V>() { }
19+
>m : <V>() => void
20+
>V : V
21+
22+
};
23+
24+
let l = <T>() => { };
25+
>l : <T>() => void
26+
><T>() => { } : <T>() => void
27+
>T : T
28+

tests/baselines/reference/unusedTypeParametersWithUnderscore.errors.txt

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(1,16): error TS6133:
22
tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(3,12): error TS6133: 'U' is declared but its value is never read.
33
tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(5,17): error TS6133: 'U' is declared but its value is never read.
44
tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(7,13): error TS6133: 'U' is declared but its value is never read.
5+
tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(8,18): error TS6133: 'W' is declared but its value is never read.
6+
tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(11,14): error TS6133: 'U' is declared but its value is never read.
57

68

7-
==== tests/cases/compiler/unusedTypeParametersWithUnderscore.ts (4 errors) ====
9+
==== tests/cases/compiler/unusedTypeParametersWithUnderscore.ts (6 errors) ====
810
function f<_T, U>() { }
911
~
1012
!!! error TS6133: 'U' is declared but its value is never read.
@@ -17,7 +19,15 @@ tests/cases/compiler/unusedTypeParametersWithUnderscore.ts(7,13): error TS6133:
1719
~
1820
!!! error TS6133: 'U' is declared but its value is never read.
1921

20-
class C<_T, U> { };
22+
class C<_T, U> {
2123
~
2224
!!! error TS6133: 'U' is declared but its value is never read.
25+
public m<_V, W>() { }
26+
~
27+
!!! error TS6133: 'W' is declared but its value is never read.
28+
};
29+
30+
let l = <_T, U>() => { };
31+
~
32+
!!! error TS6133: 'U' is declared but its value is never read.
2333

tests/baselines/reference/unusedTypeParametersWithUnderscore.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ type T<_T, U> = { };
55

66
interface I<_T, U> { };
77

8-
class C<_T, U> { };
8+
class C<_T, U> {
9+
public m<_V, W>() { }
10+
};
11+
12+
let l = <_T, U>() => { };
913

1014

1115
//// [unusedTypeParametersWithUnderscore.js]
@@ -14,6 +18,8 @@ function f() { }
1418
var C = /** @class */ (function () {
1519
function C() {
1620
}
21+
C.prototype.m = function () { };
1722
return C;
1823
}());
1924
;
25+
var l = function () { };

tests/baselines/reference/unusedTypeParametersWithUnderscore.symbols

+13-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,20 @@ interface I<_T, U> { };
1414
>_T : Symbol(_T, Decl(unusedTypeParametersWithUnderscore.ts, 4, 12))
1515
>U : Symbol(U, Decl(unusedTypeParametersWithUnderscore.ts, 4, 15))
1616

17-
class C<_T, U> { };
17+
class C<_T, U> {
1818
>C : Symbol(C, Decl(unusedTypeParametersWithUnderscore.ts, 4, 23))
1919
>_T : Symbol(_T, Decl(unusedTypeParametersWithUnderscore.ts, 6, 8))
2020
>U : Symbol(U, Decl(unusedTypeParametersWithUnderscore.ts, 6, 11))
2121

22+
public m<_V, W>() { }
23+
>m : Symbol(C.m, Decl(unusedTypeParametersWithUnderscore.ts, 6, 16))
24+
>_V : Symbol(_V, Decl(unusedTypeParametersWithUnderscore.ts, 7, 13))
25+
>W : Symbol(W, Decl(unusedTypeParametersWithUnderscore.ts, 7, 16))
26+
27+
};
28+
29+
let l = <_T, U>() => { };
30+
>l : Symbol(l, Decl(unusedTypeParametersWithUnderscore.ts, 10, 3))
31+
>_T : Symbol(_T, Decl(unusedTypeParametersWithUnderscore.ts, 10, 9))
32+
>U : Symbol(U, Decl(unusedTypeParametersWithUnderscore.ts, 10, 12))
33+

tests/baselines/reference/unusedTypeParametersWithUnderscore.types

+14-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,21 @@ interface I<_T, U> { };
1414
>_T : _T
1515
>U : U
1616

17-
class C<_T, U> { };
17+
class C<_T, U> {
1818
>C : C<_T, U>
1919
>_T : _T
20+
>U : U
21+
22+
public m<_V, W>() { }
23+
>m : <_V, W>() => void
24+
>_V : _V
25+
>W : W
26+
27+
};
28+
29+
let l = <_T, U>() => { };
30+
>l : <_T, U>() => void
31+
><_T, U>() => { } : <_T, U>() => void
32+
>_T : _T
2033
>U : U
2134

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@noUnusedParameters:true
2+
3+
function f<T>() { }
4+
5+
type T<T> = { };
6+
7+
interface I<T> { };
8+
9+
class C<T> {
10+
public m<V>() { }
11+
};
12+
13+
let l = <T>() => { };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@noUnusedLocals:true
2+
3+
function f<T>() { }
4+
5+
type T<T> = { };
6+
7+
interface I<T> { };
8+
9+
class C<T> {
10+
public m<V>() { }
11+
};
12+
13+
let l = <T>() => { };
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
//@noUnusedLocals:true
1+
//@noUnusedParameters:true
22

33
function f<_T, U>() { }
44

55
type T<_T, U> = { };
66

77
interface I<_T, U> { };
88

9-
class C<_T, U> { };
9+
class C<_T, U> {
10+
public m<_V, W>() { }
11+
};
12+
13+
let l = <_T, U>() => { };

tests/cases/fourslash/unusedTypeParametersInClass1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference path='fourslash.ts' />
22

3-
// @noUnusedLocals: true
3+
// @noUnusedParameters: true
44
////[|class greeter<T> |] {
55
////}
66

tests/cases/fourslash/unusedTypeParametersInClass2.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference path='fourslash.ts' />
22

3-
// @noUnusedLocals: true
3+
// @noUnusedParameters: true
44
////[|class greeter<X, Y> |] {
55
//// public a: X;
66
////}

tests/cases/fourslash/unusedTypeParametersInClass3.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
/// <reference path='fourslash.ts' />
33

4-
// @noUnusedLocals: true
4+
// @noUnusedParameters: true
55
////[|class greeter<X, Y, Z> |] {
66
//// public a: X;
77
//// public b: Z;

tests/cases/fourslash/unusedTypeParametersInFunction1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference path='fourslash.ts' />
22

3-
// @noUnusedLocals: true
3+
// @noUnusedParameters: true
44
//// [|function f1<T>() {}|]
55

66
verify.codeFix({

0 commit comments

Comments
 (0)