Add support for Typescript's exactOptionalPropertyTypes setting
- Dominant language
- JavaScript
- Stars
- 21.2k
- Forks
- 1.5k
- Avg merge
- 4h 57m
- Merged PRs (30d)
- 14
Description
#### Support plan
* *is this issue currently blocking your project?* (yes/no): no
* *is this issue affecting a production system?* (yes/no): no
#### Context
* *node version*: 18.13.0
* *module version*: 17.3.0
* *environment* (e.g. node, browser, native): node
* *used with* (e.g. hapi application, another framework, standalone, ...): joiful/standalone
* *any other relevant information*: tsconfig.json set with "exactOptionalPropertyTypes": true
#### What problem are you trying to solve?
We are using a stricter typescript config with exactOptionalPropertyTypes set as true, and we get TS errors when defining what an array of items can be.
```js
import Joi from 'joi';
import { array } from 'joiful';
@array()
.items(
Joi.string().guid({
version: ['uuidv1', 'uuidv2', 'uuidv3', 'uuidv4', 'uuidv5'],
}),
Joi.number(),
Joi.object()
)
.required()
identifier!: (string | number | JSONObject)[];
```
Causes this typescript error:
```
error TS2379: Argument of type 'StringSchema' is not assignable to parameter of type 'Schema' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Type 'StringSchema' is not assignable to type 'StringSchema' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Types of property 'alter' are incompatible.
Type '(targets: Record) => Schema>) => StringSchema' is not assignable to type '(targets: Record) => StringSchema'.
Types of parameters 'targets' and 'targets' are incompatible.
Type 'Record' is not assignable to type 'Record) => Schema>'.
'string' index signatures are incompatible.
Type 'SchemaFunction' is not assignable to type '(schema: StringSchema) => Schema'.
200 Joi.string().guid({
~~~~~~~~~~~~~~~~~~~
201 version: ['uuidv1', 'uuidv2', 'uuidv3', 'uuidv4', 'uuidv5'],
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202 }),
~~~~~~~~~~~~~~
```
To get around this error we have to use `any` which is not ideal, and also tell the linter to stop warning us about the use of any:
```js
@array()
.items(
Joi.string().guid({
version: ['uuidv1', 'uuidv2', 'uuidv3', 'uuidv4', 'uuidv5'],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}) as any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Joi.number() as any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Joi.object() as any
)
.required()
```
#### Do you have a new or modified API suggestion to solve the problem?
Updating the joi optional types to include `undefined` per the [TS documentation](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes) would solve the issue and add support for that setting.
Contributor guide
Assessment
This issue has not been assessed yet.