microsoft / microsoft/TypeScript
Branded string literals revert to `string` in some cases
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
🔎 Search Terms
If I create a branded string literal it seems to respect the string literal in the basic case of assigning to a property, however it loses this information and just reverts to string when assigning to a property or in a template string.
It makes sense that the brand object needs to be dropped in these cases, but rather than converting to string, it should convert to the narrower literal type.
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about branded string
⏯ Playground Link
💻 Code
type MyLiteral<S extends string> = S & {_brand: {}};
const a = 'a' as MyLiteral<'a'>;
const x: 'a' = a; // works!
const y: 'a' = `${a}`; // fails!
const z: {a: number} = {[a]: 8} // fails!
🙁 Actual behavior
For y and z, the types don't match because a is converted to string rather than 'a'
🙂 Expected behavior
The types should match in all 3 cases, x, y, z
Additional information about the issue
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked TypeScript Playground and reproduce the three assignments involving the branded literal. Trace the type checking for the template string and computed property cases, comparing them with the direct assignment. Done means both y and z accept the expected narrower literal types without regressing the existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100