ts-one-of
v0.0.1
Published
Work with GraphQL `oneOf` types in TypeScript
Downloads
428
Readme
one-of
Utility type and function for working with GraphQL oneOf types.
Example
type UserQueryFilterInput = OneOf<{
id?: string;
name?: string;
}>;
// => UserQueryInput looks like:
// { id: string; name?: undefined } | { name: string; id?: undefined };interface UserQueryFilterInput {
id?: string;
name?: string;
}
const input = oneOf<UserQueryFilterInput>({ name: 'Sophia' }, ['id', 'name']);
// => `input` is now `OneOf<UserQueryFilterInput>`
const input = oneOf<UserQueryFilterInput>({ id: 'user_abc', name: 'Sophia' }, ['id', 'name']);
// => error: more than one key set in input objectFAQ
Why does the oneOf function take its second argument?
For the same reason that Object.keys returns string[]. TypeScript uses a structual type system, which means that the following code typechecks without problem:
interface Foo {
bar?: string;
baz?: number;
}
function doSomething(foo: Foo) {
const validatedFoo = oneOf(foo);
// typechecks!
// => `validatedFoo` is now `{ invalidKey: true }`
}
const foo = {
bar: undefined,
invalidKey: true,
};
doSomething(foo);In this case, we want to throw an error because the foo object is invalid. Neither bar nor baz were set, and invalidKey is not supposed to be a valid key on our Foo type. Because TypeScript types don't exist at runtime, there is no way to detect this error if oneOf only took the object parameter.
By enforcing all keys of Foo are passed as a tuple at runtime, it's now possible to detect this error (because invalidKey isn't part of the tuple!)
interface Foo {
bar?: string;
baz?: number;
}
function doSomething(foo: Foo) {
const validatedFoo = oneOf(foo, ['bar', 'baz']);
// => throws an error as we would expect
}
const foo = {
bar: undefined,
invalidKey: true,
};
doSomething(foo);