Don't throw error when passing objects with additional fields
See original GitHub issueProblem
Typescript actively uses duck typing, which allows us to significantly reduce the amount of code in comparison with other languages, since we do not need to write many adapters and intermediate classes, while still guaranteeing full-fledged type safety. However, I came across an unpleasant feature of the prisma, which throws an error in cases when I pass to methods, for example create, objects that have extra fields. However, in theory, this does not prevent the prisma from correctly interpreting and executing a query to the database.
We already have a large project, which we will transfer from typeORM to prisma. TypeORM was type-insecure, but it allowed the transfer of objects with extra fields. As a result, it turns out that now we need to make up to hundreds of new classes that will not do anything, but will just exactly match the shape of the prism models.
For example, in DB(respectively in prisma) we have model User
, with next fields: (userId, userName, password)
. And from client I getting similar object with type UserDto
, with next fields: (userName, password, timestamp)
. And I want to save it to DB, but without timestamp
. Prisma throw error in runtime and say that object have unknown fields timestamp
. But it have compiled successfully
Suggested solution
Since the situation is not lonely, and there are a lot of such places in the code, it seems to me that the best solution would be to simply remove this error, since the extra fields do not interfere with the correct request, but can only indirectly say that the user may , transfers the wrong object that it wants, and in most cases it learns about it at the compilation stage, due to duck typing. But, we don’t have to write tons of intermediate classes, adapters, transfers, etc.
Alternatives
if you think that this is a problem, it seems to me that you should at least not let the application compile if objects of types with extra fields are passed. Since it was a big surprise for me that the application crashed at runtime, having received a type object with extra fields, because this was the expected behavior, the types are defined in the code
Issue Analytics
- State:
- Created 3 years ago
- Reactions:13
- Comments:9 (1 by maintainers)
Top GitHub Comments
It’s a good question and I think this problem is essentially with Typescript, since it can come up in other ways too. For example a rest api can accidentally return extra (private) data if a larger type is spread from an upstream stage. I’m not super close to the development of the language but it looks like it’s an ongoing thing people want to improve: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-1117135412
If you’re writing typescript you’re pretty much assuming that everything that’s true at build time is true at run time – it’s a build time mindset. The spread operator to me always means “take the fields you need from this to satisfy the type of the input”. Rather than “overload the object beyond its type to include everything in this” (which is unfortunately the actual result). If I was a pure JS programmer maybe I would always think the other way around!
When I’m writing code to interact with Prisma I’m super happy because it has really great typings that ensure that things make sense at build time based on the schema. From that perspective Prisma is already preventing me from asking it to accept data that isn’t in the schema.
At runtime I think Prisma needs to check the types of some fields and throw errors, because not doing so will cause data problems or result in less friendly DB errors being thrown. But checking for excess fields is complaining about something that can’t do any damage and isn’t the programmer’s intent.
A subtle subset of the spread operator problem is where the extra fields caught by the spread at runtime are actually valid in the schema… In that case it would not error but it would do damage (because what I think I’m doing at build time isn’t what I’m actually doing at runtime). Don’t think there’s anything Prisma can do about that situation tho, unless perhaps with a future version of typescript.
Maybe allowing us to opt out of strict excess field checking would be enough to make it safer at runtime? To be clear I mean safety in terms of less crashes - the data safety is the same either way.
@KieranHarper
Unit testing is really the only way to improve safety on that because it’s implementation specific.
Have to say this error (throwing at runtime) caught me by surprise (fortunately my e2e tests caught it before it went out).