fix detection of single usage of type parameter

This commit is contained in:
Gabriela Araujo Britto 2025-02-04 13:03:07 -08:00
parent c50b5e718a
commit 684f733192
5 changed files with 142 additions and 1 deletions

View File

@ -46040,7 +46040,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function isReferenced(node: Node): boolean {
if (isTypeReferenceNode(node)) {
return isReferenceToTypeParameter(typeParam, node);
return isReferenceToTypeParameter(typeParam, node) || some(node.typeArguments, isReferenced);
}
if (isTypeQueryNode(node)) {
return isTypeParameterPossiblyReferenced(typeParam, node);

View File

@ -0,0 +1,26 @@
dependentReturnType11.ts(13,9): error TS2322: Type '"woof"' is not assignable to type 'Ret<T>'.
dependentReturnType11.ts(15,5): error TS2322: Type '"meow"' is not assignable to type 'Ret<T>'.
==== dependentReturnType11.ts (2 errors) ====
type Foo<T extends boolean> = {
name: string,
isDog: T,
}
type Ret<T> =
T extends true ? "woof" :
T extends false? "meow" :
never;
function example1<T extends boolean>(param1: T, param2: Foo<T>): Ret<T> {
if (param1) {
return "woof";
~~~~~~
!!! error TS2322: Type '"woof"' is not assignable to type 'Ret<T>'.
}
return "meow"
~~~~~~
!!! error TS2322: Type '"meow"' is not assignable to type 'Ret<T>'.
}

View File

@ -0,0 +1,46 @@
//// [tests/cases/compiler/dependentReturnType11.ts] ////
=== dependentReturnType11.ts ===
type Foo<T extends boolean> = {
>Foo : Symbol(Foo, Decl(dependentReturnType11.ts, 0, 0))
>T : Symbol(T, Decl(dependentReturnType11.ts, 0, 9))
name: string,
>name : Symbol(name, Decl(dependentReturnType11.ts, 0, 31))
isDog: T,
>isDog : Symbol(isDog, Decl(dependentReturnType11.ts, 1, 17))
>T : Symbol(T, Decl(dependentReturnType11.ts, 0, 9))
}
type Ret<T> =
>Ret : Symbol(Ret, Decl(dependentReturnType11.ts, 3, 1))
>T : Symbol(T, Decl(dependentReturnType11.ts, 5, 9))
T extends true ? "woof" :
>T : Symbol(T, Decl(dependentReturnType11.ts, 5, 9))
T extends false? "meow" :
>T : Symbol(T, Decl(dependentReturnType11.ts, 5, 9))
never;
function example1<T extends boolean>(param1: T, param2: Foo<T>): Ret<T> {
>example1 : Symbol(example1, Decl(dependentReturnType11.ts, 8, 10))
>T : Symbol(T, Decl(dependentReturnType11.ts, 10, 18))
>param1 : Symbol(param1, Decl(dependentReturnType11.ts, 10, 37))
>T : Symbol(T, Decl(dependentReturnType11.ts, 10, 18))
>param2 : Symbol(param2, Decl(dependentReturnType11.ts, 10, 47))
>Foo : Symbol(Foo, Decl(dependentReturnType11.ts, 0, 0))
>T : Symbol(T, Decl(dependentReturnType11.ts, 10, 18))
>Ret : Symbol(Ret, Decl(dependentReturnType11.ts, 3, 1))
>T : Symbol(T, Decl(dependentReturnType11.ts, 10, 18))
if (param1) {
>param1 : Symbol(param1, Decl(dependentReturnType11.ts, 10, 37))
return "woof";
}
return "meow"
}

View File

@ -0,0 +1,51 @@
//// [tests/cases/compiler/dependentReturnType11.ts] ////
=== dependentReturnType11.ts ===
type Foo<T extends boolean> = {
>Foo : Foo<T>
> : ^^^^^^
name: string,
>name : string
> : ^^^^^^
isDog: T,
>isDog : T
> : ^
}
type Ret<T> =
>Ret : Ret<T>
> : ^^^^^^
T extends true ? "woof" :
>true : true
> : ^^^^
T extends false? "meow" :
>false : false
> : ^^^^^
never;
function example1<T extends boolean>(param1: T, param2: Foo<T>): Ret<T> {
>example1 : <T extends boolean>(param1: T, param2: Foo<T>) => Ret<T>
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
>param1 : T
> : ^
>param2 : Foo<T>
> : ^^^^^^
if (param1) {
>param1 : T
> : ^
return "woof";
>"woof" : "woof"
> : ^^^^^^
}
return "meow"
>"meow" : "meow"
> : ^^^^^^
}

View File

@ -0,0 +1,18 @@
// @noEmit: true
type Foo<T extends boolean> = {
name: string,
isDog: T,
}
type Ret<T> =
T extends true ? "woof" :
T extends false? "meow" :
never;
function example1<T extends boolean>(param1: T, param2: Foo<T>): Ret<T> {
if (param1) {
return "woof";
}
return "meow"
}