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

Lines changed: 2 additions & 2 deletions
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.
Lines changed: 33 additions & 0 deletions
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+
Lines changed: 25 additions & 0 deletions
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 () { };
Lines changed: 27 additions & 0 deletions
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+
Lines changed: 28 additions & 0 deletions
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+
Lines changed: 25 additions & 0 deletions
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 () { };
Lines changed: 27 additions & 0 deletions
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+
Lines changed: 28 additions & 0 deletions
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

Lines changed: 12 additions & 2 deletions
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

Lines changed: 7 additions & 1 deletion
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 () { };

0 commit comments

Comments
 (0)