Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix input objects allowing unexpected keys. #229

Closed

Conversation

igalklebanov
Copy link
Member

@igalklebanov igalklebanov commented Nov 15, 2022

Exilen#9116 & Chito#7124 were going back & forth on discord around updateTable(...).set(...) usage and came upon a typescript issue that allows unexpected columns when using spread operator and stuff.

interface Task {
  completed_at: Date
  do_at: Date
}

const dinosaurs = ['t-rex'];

const task = await db.updateTable('tasks').set({
  ...(completed_at !== undefined && { completed_at }),
  ...(do_at !== undefined && { do_at }),
  ...(dinosaurs !== undefined && { dinosaurs }), // dinosaurs doesn't exist on 'tasks', but still no ts error.
  ...{ age: 5 }, // nope, no ts error.
})

This PR aims at not allowing unexpected keys, no matter what... and without breaking autocompletion.

  • implement stricter UpdateQueryBuilder.set(...).
  • implement stricter InsertQueryBuilder.values(...).
  • implement stricter InsertQueryBuilder.onDuplicateKeyUpdate(...).
  • implement stricter OnConflictBuilder.doUpdateSet(...).

tsd is both not finding an error & finding an error 🙄 for line 42 @ test/typings/test-d/update.test-d.ts when exactOptionalPropertyTypes is enabled. Posted an issue @ tsd. Disabling this option in tsd tests for now.


This is currently breaking usage of sql template tag in these functions.. now requiring to explicitly state a return type that aligns with column type's Update/Insert type. not sure this is a bad thing...

Another breaking change now forces consumers to pass a non-empty array @ InsertQueryBuilder.values(...). I'm 50-50 on this since typescript doesn't infer non-empty after checking length, so this might be annoying to consumers. Decided to remove this. If consumer has to pass an argument that was assigned to elsewhere, she has to use as, write a type guard or, if on >=4.9, use satisfies. All these escapes potentially skip the more important check of unexpected keys per item.

@igalklebanov igalklebanov added api Related to library's API bug Something isn't working typescript Related to Typescript labels Nov 15, 2022
@igalklebanov igalklebanov added the breaking change Includes breaking changes label Nov 16, 2022
@igalklebanov igalklebanov marked this pull request as ready for review November 19, 2022 11:15
@igalklebanov igalklebanov marked this pull request as draft November 19, 2022 11:41
@igalklebanov igalklebanov marked this pull request as ready for review November 19, 2022 14:15
@koskimas
Copy link
Member

Sorry it took so long again 😬

I'm on the fence with this one. We're actively fighting against typescript here and this feels like a hack. This also makes the types unreadable, but on the other hand, we already have that problem in most places.

Is the added benefit worth the complexity here? People should be familiar with how typescript works and it shouldn't be a surprise in most cases that interfaces accept extra properties.

@igalklebanov
Copy link
Member Author

Sorry it took so long again 😬

IRL > whatever it is that we do in this site. No worries m8.

I'm on the fence with this one. We're actively fighting against typescript here and this feels like a hack. This also makes the types unreadable, but on the other hand, we already have that problem in most places.

Is the added benefit worth the complexity here? People should be familiar with how typescript works and it shouldn't be a surprise in most cases that interfaces accept extra properties.

Yeah it's a tough one. People had been whining about this since like '16 and there's still no fix from TS crew.

On one hand it does align with our promise of type-safety and will reduce chances of runtime errors for consumers..
On the other it's "unsafe" to maintain and might do some harm if the language changes its behavior.

I guess we should close this and maybe go back to it later if its viable and a lot of people beg for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Related to library's API breaking change Includes breaking changes bug Something isn't working typescript Related to Typescript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants