typia
typia copied to clipboard
Error when validating Prisma.JsonValue
Issue with Prisma.JsonValue
Prisma has a JsonValue
type, which is defined as below.
export declare type JsonValue = string | number | boolean | JsonObject | JsonArray | null;
export declare type JsonObject = {
[Key in string]?: JsonValue;
};
export declare interface JsonArray extends Array<JsonValue> {}
Following to above definition, an array with primitive values still conforms to JsonValue
.
So, arrays like [1, 2, 3]
, ['hello', 'world']
or [1, 'hello', true]
are all valid JsonValue
.
However, typia throws an error like this.
typia.validate<JsonArray>([1, 2, 3]);
{
success: false,
errors: [
{
path: '$input',
expected: '(JsonArray | JsonObject | boolean | null | number | string)',
value: [Array]
}
],
data: undefined
}
This is very weird, because when you make the same type as a type alias, this one passes like this.
type TJsonArray = Array<JsonValue>;
typia.validate<TJsonArray>([1, 2, 3]);
// or this also works
// typia.validate<Array<JsonValue>>([1, 2, 3]);
{ success: true, errors: [], data: [ 1, 2, 3 ] }
type TJsonArray = Array<JsonValue>;
and interface IJsonArray extends Array<JsonValue> {}
should be the same as long as I understand, and other library such as zod
doesn't have the same issue. ~~Or my zod implementation might be wrong.~~
So, it seems the way how typia uses interface and type alias is causing the issue.
Reproduction
I made a small reproduction project here.
change the DATABASE_URL
in .env
to yours, and run
$ pnpm install
$ pnpm migrate
$ pnpm dev
to start the project.
Then console will print things like this
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [NestFactory] Starting Nest application...
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [InstanceLoader] PrismaModule dependencies initialized +299ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [InstanceLoader] AppModule dependencies initialized +2ms
zod:: { success: true, data: [ 1, 'two', null ] }
typia:: {
success: false,
errors: [
{
path: '$input',
expected: '(JsonArray | JsonObject | boolean | null | number | string)',
value: [Array]
}
],
data: undefined
}
Array<JsonValue>:: { success: true, errors: [], data: [ 1, 'two', null ] }
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [InstanceLoader] UsersModule dependencies initialized +3ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [RoutesResolver] AppController {/}: +30ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [RoutesResolver] UsersController {/users}: +0ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [RouterExplorer] Mapped {/users, POST} route +0ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [RouterExplorer] Mapped {/users/:id, GET} route +0ms
[Nest] 75843 - 11/13/2023, 10:53:13 PM DEBUG [PrismaService] Prisma connected
[Nest] 75843 - 11/13/2023, 10:53:13 PM LOG [NestApplication] Nest application successfully started +1ms
some example codes with validating is in src/users/users.controller.ts
.
about database connection and schema
It requires PostgreSQL because I want to ensure that Prisma and PostgreSQL does not take this as an issue. It's only typia related validations saying an array is not a valid JsonValue.
You can find this when sending an api request to POST /users
. It will create a data in the database, but will throw validation error while serializing response body with Nestia.
Also, it doesn't look like pnpm issue related to node_modules
structure. I tried with npm, or hoisted pnpm but it was the same.
Your type definition is invalid.
The JsonValue
must be defined like below.
type JsonValue = string | number | boolean | JsonObject | JsonArray | null;
type JsonObject = {
[Key in string]?: JsonValue;
};
type JsonArray = Array<JsonValue>;
At first, you've not to extends the Array
type through the interface (interface JsonArray extends Array<JsonValue>
.
The definition means that JsonArray
is not an Array
type, but an Object
type which has length: number
property and [n: number]: T
accessor. Therefore, it would be considered to not Array
, but some ArrayLike
Object
type. The reason why typia
had reported you that [1, 2, 3]
is invalid type also base on the fact. It's not a bug, but exactly spec.
If you define the JsonArray
like above, then there will not be any problem.
I found that Prisma
actually defined JsonArray
type to extending the Array
.
It is bug of Prisma, so I'll report issue about that.
Prisma issue had been delayed too much time.
Therefore, I did hard coded for this case.
Now, upgrade to v5.5.5
, then be supported.