microsoft / microsoft/TypeScript
Intersection type in template literal is not reduced to its bare type
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.4k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
🔎 Search Terms
template literal, intersection type
🕗 Version & Regression Information
- This changed between versions 5.0 and 5.1
- This changed in commit or PR #48034 #52345 #54648
⏯ Playground Link
💻 Code
type StringType<K extends string> = K extends string & infer U
? [K, U] extends [U, K]
? {} extends { [P in `${K}`]: unknown }
? 'templateLiteral'
: 'stringLiteral'
: 'string'
: never
type R1 = StringType<string>
// ^? type R1 = "string"
type R2 = StringType<string & { a: 1 }>
// ^? type R2 = "string"
type R3 = StringType<'abc'>
// ^? type R3 = "stringLiteral"
type R4 = StringType<'abc' & { a: 1 }>
// ^? type R4 = "templateLiteral" <-- should be "stringLiteral"
type R5 = StringType<`${number}`>
// ^? type R5 = "templateLiteral"
type R6 = StringType<`${number}` & { a: 1 }>
// ^? type R6 = "templateLiteral"
🙁 Actual behavior
type R = `${'abc' & { a: 1 }}`
// did not reduce => `${'abc' & { a: 1 }}`
🙂 Expected behavior
type R = `${'abc' & { a: 1 }}`
// should reduce to => `${'abc'}`
// => `abc`
Additional information about the issue
I mentioned this in #54648 after it is closed. It is limiting our ability to write the types that works with string literal and template literal and there is no alternative way to workaround that.
I'm suggesting this issue should be fixed and restore the behavior in 5.0.
Here is my original comment:
This behavior is causing a few types in type-plus to fail (e.g. IsTemplateLiteral, IsStringLiteral, Omit, IsNegative, etc) https://github.com/unional/type-plus/issues/429.
In term of soundness, IMO it does make sense that ${string & { a: 1 }} to be reduced to ${string}.
in JS, it would be:
const extendedStr = Object.assign('abc', { a: 1 })
console.log(`${extendedStr}`) // 'abc'
the reasoning being the toString(): string remains unchanged thus the resulting type should be safe to reduce.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Reproduziere die Regression im verknüpften TypeScript Playground und vergleiche die angezeigten R4- und R6-Ergebnisse über die Versionen 5.0 und 5.1 hinweg. Verwende die zitierten Commits und Pull Requests (#48034, #52345 und #54648) als Ausgangspunkt für die Historie; abgeschlossen ist dies, wenn R4 auf das String-Literal-Ergebnis reduziert wird, während die anderen Beispiele ihre erwarteten Klassifizierungen beibehalten.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 35/100