microsoft / microsoft/TypeScript
Intersection type in template literal is not reduced to its bare type
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
🔎 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.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Riproduci la regressione nel TypeScript Playground collegato, confrontando i risultati mostrati di R4 e R6 tra le versioni 5.0 e 5.1. Usa i commit e le pull request citati (#48034, #52345 e #54648) come punto di partenza della cronologia; il lavoro è completato quando R4 si riduce al risultato string-literal, mentre gli altri esempi mantengono le classificazioni previste.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100