[BUG]: It's merging types that are not the same
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- tooling
Research direction
Reproduce the JSON example through app.quicktype.io and the npm entry point with TypeScript output, then trace the type-merging behavior that combines partially overlapping object shapes. No source file or test is named in the issue; done means the generated types preserve the distinct input structures without incorrect optional properties, with regression coverage for this example.
Written by the indexing model from the issue text.
Description
Types that are "similar" I guess, but not quite the same, are being merged, leading to weird optional properties in the resulting types, where they should not be.
Issue Type
output
Context (Environment, Version, Language)
Input Format: json
Output Language: typescript
CLI, npm, or app.quicktype.io: npm & app
Version: 26.0.0
Description
I'm using it to generate types for strong-typed translation keys. And this bug is breaking that.
Input Data
{
"User": {
"Profile": {
"Title": "Mijn profiel",
"Error": "Serverfout, probeer het nog een keer",
"Success": "Profiel succesvol bijgewerkt",
"Submit": "Wijzig gegevens",
"Fields": {
"Email": "E-mailadres",
"FirstName": "Voornaam",
"LastName": "Achternaam"
}
},
"ChangePassword": {
"Title": "Wachtwoord wijzigen",
"Error": "Wachtwoord wijzigen is mislukt. Probeer het later nog eens.",
"Success": "Wachtwoord is gewijzigd. De volgende dat u inlogt, kunt u uw nieuwe wachtwoord gebruiken.",
"Submit": "Wijzig wachtwoord",
"Fields": {
"OldPassword": "Huidig wachtwoord",
"NewPassword": "Nieuw wachtwoord",
"ConfirmPassword": "Herhaal wachtwoord ter bevestiging"
}
},
"Notifications": {
"Title": "Notificatievoorkeuren",
"Error": "Notificatievoorkeuren konden niet worden bewaard. Probeer het later nog eens.",
"Success": "Notificatievoorkeuren zijn bewaard.",
"Submit": "Voorkeuren bewaren"
}
}
}
Expected Behaviour / Output
Do not merge types that are mergeable, so it should become something like:
export type Welcome = {
User: User;
}
export type User = {
Profile: Profile;
ChangePassword: ChangePassword;
Notifications: Notifications;
}
export type Profile = {
Title: string;
Error: string;
Success: string;
Submit: string;
Fields: ProfileFields;
}
export type Notifications = {
Title: string;
Error: string;
Success: string;
Submit: string;
}
export type Profile = {
Title: string;
Error: string;
Success: string;
Submit: string;
Fields: ProfileFields;
}
export type ProfileFields = {
Email: string;
FirstName: string;
LastName: string;
}
export type ChangePasswordFields = {
OldPassword: string;
NewPassword: string;
ConfirmPassword: string;
}
Current Behaviour / Output
Instead, it's just willy-nilly merging types that are obviously different, but just happen to be partially overlapping:
export type Welcome = {
User: User;
}
export type User = {
Profile: ChangePassword;
ChangePassword: ChangePassword;
Notifications: ChangePassword;
}
export type ChangePassword = {
Title: string;
Error: string;
Success: string;
Submit: string;
Fields?: Fields;
}
export type Fields = {
OldPassword?: string;
NewPassword?: string;
ConfirmPassword?: string;
Email?: string;
FirstName?: string;
LastName?: string;
}
Why is it doing that?
Steps to Reproduce
- Paste the JSON above into the app
- Set output language to Typescript
Options are not relevant. And also, I think it does a similar thing in other output languages, although I'm not an expert in all of them.
Possible Solution
If partial overlaps must be merged for some reason, do it correctly, with extends. Not by smashing them together and making everything optional. Or better yet, to keep is simple - don't merge. At least don't produce an output that no longer matches the input precisely.
- Dominant language
- TypeScript
- Stars
- 13.9k
- Forks
- 1.2k
- Avg merge
- 8h 14m
- Merged PRs (30d)
- 368
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.
More from glideapps/quicktype
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
CI
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 5/5 Over a week Newbie friendliness 45/100
-
[BUG]: Openbug
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 3/5 1-2 days Newbie friendliness 58/100
All issues in glideapps/quicktype
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
danielmiessler/LifeOS#2218 ·