Skip to content

Commit

Permalink
Make "required" optional in TypeScript typings
Browse files Browse the repository at this point in the history
  • Loading branch information
LinusU committed Aug 10, 2018
1 parent 45b9708 commit 88dad89
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
10 changes: 9 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type AnySchema = NullSchema | BooleanSchema | NumberSchema | StringSchema | AnyEnumSchema | AnyArraySchema | AnyObjectSchema
type AnySchema = NullSchema | BooleanSchema | NumberSchema | StringSchema | AnyEnumSchema | AnyArraySchema | AnyObjectSchema | AnyAllOptionalObjectSchema
type StringKeys<T> = (keyof T) & string

interface NullSchema {
Expand Down Expand Up @@ -36,6 +36,13 @@ interface ObjectSchema<Properties extends Record<string, AnySchema>, Required ex
required: Required[]
}

interface AnyAllOptionalObjectSchema extends AllOptionalObjectSchema<Record<string, AnySchema>> {}
interface AllOptionalObjectSchema<Properties extends Record<string, AnySchema>> {
additionalProperties?: boolean
type: 'object'
properties: Properties
}

interface ArrayFromSchema<ItemSchema extends AnySchema> extends Array<TypeFromSchema<ItemSchema>> {}

type ObjectFromSchema<Properties extends Record<string, AnySchema>, Required extends StringKeys<Properties>> = {
Expand All @@ -50,6 +57,7 @@ type TypeFromSchema<Schema extends AnySchema> = (
: Schema extends StringSchema ? string
: Schema extends ArraySchema<infer ItemSchema> ? ArrayFromSchema<ItemSchema>
: Schema extends ObjectSchema<infer Properties, infer Required> ? ObjectFromSchema<Properties, Required>
: Schema extends AllOptionalObjectSchema<infer Properties> ? ObjectFromSchema<Properties, never>
: never
)

Expand Down
18 changes: 18 additions & 0 deletions test/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,21 @@ if (metricValidator(input)) {
assertType<'page-view'>(input.name)
assertType<string>(input.page)
}

const noRequiredFieldsValidator = createValidator({
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'string' },
c: { type: 'string' }
}
})

if (noRequiredFieldsValidator(input)) {
if (typeof input.a !== 'string') assertType<undefined>(input.a)
if (typeof input.b !== 'string') assertType<undefined>(input.b)
if (typeof input.c !== 'string') assertType<undefined>(input.c)
if (typeof input.a !== 'undefined') assertType<string>(input.a)
if (typeof input.b !== 'undefined') assertType<string>(input.b)
if (typeof input.c !== 'undefined') assertType<string>(input.c)
}

0 comments on commit 88dad89

Please sign in to comment.