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

Allow an explicitly specified infer type #782

Closed
ssalbdivad opened this issue Jun 3, 2023 Discussed in #781 · 8 comments
Closed

Allow an explicitly specified infer type #782

ssalbdivad opened this issue Jun 3, 2023 Discussed in #781 · 8 comments

Comments

@ssalbdivad
Copy link
Member

Discussed in #781

Originally posted by afoures June 1, 2023
Hi,

Is there a way to type check schema implementation from an existing type?

Something like this:

import { type, union } from "arktype";

interface Owner {
  name: string;
}

interface Dog {
  name: string;
  age: number;
  owner?: Owner
}

// I would love to be able to create a schema from an existing type in a fully type safe way
const owner = type<Owner>({ name: 'string' });
const dog = type<Dog>({ age: 'integer>0', name: 'string', 'owner?': owner });

// for example this should error, because owner is not defined as possibly undefined
const dog = type<Dog>({ age: 'integer>0', name: 'string', owner });

Related issue from zod -> colinhacks/zod#372

Thanks to @afoures for submitting this! Would definitely be a valuable feature. Currently you can do something like this:

export const user: Type<{ name: string, age: number }> = type({
    name: "string",
    age: "number"
})

But TS's comparison is structural and covariant, i.e. you could add extra fields to your validator and it would still work as long as everything in the type itself is covered.

I tried adding an in out annotation to Type's inference parameter, but it broke a bunch of other things I'd have to look into, so I'm creating this issue and adding it to the backlog to create a dedicated API for this.

If in the meantime you'd benefit from something like the above, feel free to use that, or you could write a custom function to do an equals comparison on the types as an extra validation step if needed.

@Dimava
Copy link
Contributor

Dimava commented Jun 12, 2023

I would propose Type<V>.expectType<T>(): Equals<T, V> ? T : TSError<'type doesn't match'>

@ssalbdivad
Copy link
Member Author

ssalbdivad commented Jun 12, 2023

Have a working implementation for this! Autocomplete for keys, optional keys, works for tuples, etc.! Will add to the next release (may still change the name) 😊

DeclaredTypes.mp4

@ssalbdivad
Copy link
Member Author

ssalbdivad commented Jun 12, 2023

Ended up going with:

type Expected = { a: string; b?: number }
const t = declare<Expected>().type({
    a: "string",
    "b?": "number"
})

Will add declarations for scope in the future: #791

@afoures
Copy link

afoures commented Jun 15, 2023

this is really nice, thank you very much !

@afoures
Copy link

afoures commented Feb 17, 2024

hello, is there any news regarding this? it seem that declare is not available

@ssalbdivad
Copy link
Member Author

@afoures Yes, very sorry for the delay! This is in the upcoming 2.0 release.

I will close this issue once it is merged and published. In the meantime I've been publishing a few preview dev builds, feel free to check out the ArkType Discord if interested.

@ssalbdivad
Copy link
Member Author

@afoures This is available in 2.0.0-dev.10. Keep an eye out for docs soon!

@afoures
Copy link

afoures commented May 2, 2024

thanks for the heads up! 🙏🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done (merged or closed)
Development

No branches or pull requests

3 participants