Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export Schema type from TypeScript typings #170

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

LinusU
Copy link
Collaborator

@LinusU LinusU commented Aug 13, 2018

This is very convenient for two things:

  1. When declaring your own functions that accepts a schema

  2. When putting a schema in a variable before passing it to createValidator, as without this the type information on string literals gets erased, and your schema will not be accepted as input:

Not working:

import createValidator = require('is-my-json-valid')

// mySchema will have the type `{ type: string }`, which is not a valid Schema type
const mySchema = { type: 'number' }

// Error: Type `{ type: string }` is not assignable...
createValidator(mySchema)

Working:

import createValidator = require('is-my-json-valid')

const mySchema: createValidator.Schema = { type: 'number' }

createValidator(mySchema)

@LinusU
Copy link
Collaborator Author

LinusU commented Aug 13, 2018

Hmmm, without existential types (microsoft/TypeScript#14466) this will have the same problem as we currently have with nested object properties.

Basically, this will only work well for primitive type schemas.

In use case 1, the problem will be that to get any meaningful return value that function will need to have all the same overloads that we are defining in our Factory interface.

In use case 2, the type will quickly be returned as never as this will only prevent the most top-level type widening to happen. Basically, adding only the ability to save primitive schemas in variables.

This could potentially be helped by exporting all of the different types of schemas, but that will just push much of the burden of doing workarounds (basically overloading) that we are doing internally, externally. I don't think that that is a good road to go down.

With that, I'm not sure it makes sense to merge this before existential types are fixed. I think that with that merged, we would be able to define a single Schema type, and also a single TypeToSchema<Schema> type that returns the parsed type...


Hmm, actually realised that I think the problem should come from type-erasing a specific schema into a generic Schema, which then obviously cannot be mapped into a type. But for some reason this works:

import createValidator = require('is-my-json-valid')

const input = null as unknown
const mySchema: createValidator.Schema = { type: 'number' }

const myValidator = createValidator(mySchema)

if (myValidator(input)) {
  // input is a number here
}

Seems like the difference lies in const foo: Type = foobar() instead of const foo = foobar() as Type.

Hmmmm 🤔

@sirreal
Copy link

sirreal commented Aug 11, 2019

Do you have a recommended way forward for folks who want to type schemas? Can you elaborate the kind of issues we might hit?

There's a roundabout way to get to the inner schema type:

export function doSomethingWithSchemas(
	schema: Parameters< typeof import('is-my-json-valid') >[0]
) { /* … */ }

But I'd like to understand what the problem is with using this type, it's not immediately clear to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants