Skip to content

Commit 7160756

Browse files
authored
Merge pull request #167 from mafintosh/ts-required
Make "required" optional in TypeScript typings
2 parents 20b299d + 88dad89 commit 7160756

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

index.d.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type AnySchema = NullSchema | BooleanSchema | NumberSchema | StringSchema | AnyEnumSchema | AnyArraySchema | AnyObjectSchema
1+
type AnySchema = NullSchema | BooleanSchema | NumberSchema | StringSchema | AnyEnumSchema | AnyArraySchema | AnyObjectSchema | AnyAllOptionalObjectSchema
22
type StringKeys<T> = (keyof T) & string
33

44
interface NullSchema {
@@ -36,6 +36,13 @@ interface ObjectSchema<Properties extends Record<string, AnySchema>, Required ex
3636
required: Required[]
3737
}
3838

39+
interface AnyAllOptionalObjectSchema extends AllOptionalObjectSchema<Record<string, AnySchema>> {}
40+
interface AllOptionalObjectSchema<Properties extends Record<string, AnySchema>> {
41+
additionalProperties?: boolean
42+
type: 'object'
43+
properties: Properties
44+
}
45+
3946
interface ArrayFromSchema<ItemSchema extends AnySchema> extends Array<TypeFromSchema<ItemSchema>> {}
4047

4148
type ObjectFromSchema<Properties extends Record<string, AnySchema>, Required extends StringKeys<Properties>> = {
@@ -50,6 +57,7 @@ type TypeFromSchema<Schema extends AnySchema> = (
5057
: Schema extends StringSchema ? string
5158
: Schema extends ArraySchema<infer ItemSchema> ? ArrayFromSchema<ItemSchema>
5259
: Schema extends ObjectSchema<infer Properties, infer Required> ? ObjectFromSchema<Properties, Required>
60+
: Schema extends AllOptionalObjectSchema<infer Properties> ? ObjectFromSchema<Properties, never>
5361
: never
5462
)
5563

test/typings.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ const personValidator = createValidator({
4949

5050
if (personValidator(input)) {
5151
assertType<string>(input.name)
52-
assertType<number | undefined>(input.age)
53-
input.age === undefined
54-
input.age === 1
52+
if (typeof input.age !== 'undefined') assertType<number>(input.age)
53+
if (typeof input.age !== 'number') assertType<undefined>(input.age)
5554
}
5655

5756
const namesValidator = createValidator({
@@ -139,7 +138,8 @@ const user2Validator = createValidator({
139138

140139
if (user2Validator(input)) {
141140
assertType<{ first: string | undefined, last: string }>(input.name)
142-
assertType<string | undefined>(input.name.first)
141+
if (typeof input.name.first !== 'undefined') assertType<string>(input.name.first)
142+
if (typeof input.name.first !== 'string') assertType<undefined>(input.name.first)
143143
assertType<string>(input.name.last)
144144

145145
if (input.items !== undefined) {
@@ -165,7 +165,9 @@ const specificValuesValidator = createValidator({
165165
})
166166

167167
if (specificValuesValidator(input)) {
168-
assertType<true | 1000 | 'XX'>(input)
168+
if (input !== true && input !== 1000) assertType<'XX'>(input)
169+
if (input !== 1000 && input !== 'XX') assertType<true>(input)
170+
if (input !== 'XX' && input !== true) assertType<1000>(input)
169171
}
170172

171173
const metricValidator = createValidator({
@@ -184,3 +186,21 @@ if (metricValidator(input)) {
184186
assertType<'page-view'>(input.name)
185187
assertType<string>(input.page)
186188
}
189+
190+
const noRequiredFieldsValidator = createValidator({
191+
type: 'object',
192+
properties: {
193+
a: { type: 'string' },
194+
b: { type: 'string' },
195+
c: { type: 'string' }
196+
}
197+
})
198+
199+
if (noRequiredFieldsValidator(input)) {
200+
if (typeof input.a !== 'string') assertType<undefined>(input.a)
201+
if (typeof input.b !== 'string') assertType<undefined>(input.b)
202+
if (typeof input.c !== 'string') assertType<undefined>(input.c)
203+
if (typeof input.a !== 'undefined') assertType<string>(input.a)
204+
if (typeof input.b !== 'undefined') assertType<string>(input.b)
205+
if (typeof input.c !== 'undefined') assertType<string>(input.c)
206+
}

0 commit comments

Comments
 (0)