Skip to content

Template literals not widening to a union type when spread as function parameters #46768

Closed
@loc

Description

@loc

Bug Report

When provided with certain template literal types, array generics do not widen to a union array type when spread as function parameters, but does work correctly if not spread.

🔎 Search Terms

template literals, generic, union, spread, rest, parameters, 2345

🕗 Version & Regression Information

Reproduced on v4.5.0-beta, v4.4.4 and v4.3.5. Prior to v4.3, there was another bug with template literals that may occlude this one, so hard to say if it's a regression or just inherent to how template literals were written initially.

⏯ Playground Link

Link to playground

💻 Code

type DotString = `${string}.${string}.${string}`;
function noSpread<P extends DotString>(args: P[]): P { return true as any; }
function spread<P extends DotString>(...args: P[]): P { return true as any; }

noSpread([`1.${'2'}.3`, `1.${'2'}.4`]);                     // fine: "1.2.3" | "1.2.4"
noSpread([`1.${'2' as string}.3`, `1.${'2' as string}.4`]); // fine: `1.${string}.3` | `1.${string}.4`

spread(`1.${'2'}.3`, `1.${'2'}.4`);                         // fine: "1.2.3" | "1.2.4"
spread(`1.${'2' as string}.3`, `1.${'2' as string}.4`);     // error: Argument of type '`1.${string}.4`' is not assignable to parameter of type '`1.${string}.3`'.(2345)

🙁 Actual vs. Expected behavior

The second call to spread() should have the same return type as the second call to noSpread(), but there is an error on the second argument where the generic seems to be stuck on the narrowed first type.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions