Open cthogg opened 3 years ago
Hey @cthogg thanks for the report. Can you try to pare it down to the most minimal reproduction? (Eg. getting rid of the nested objects, intermediate functions, etc. if possible.)
Thanks, I think this is the most minimal reproduction I can make that exhibits similar behavior:
import { Describe, validate, string } from 'superstruct'
const fn = <T>(struct: Describe<T>) => validate(null, struct)
const S = string()
fn(S) // fails
Argument of type 'Struct<string, null>' is not assignable to parameter of type 'Describe<string | null>'.
Types of property 'refiner' are incompatible.
Type '(value: string, context: Context) => Iterable<Failure>' is not assignable to type '(value: string | null, context: Context) => Iterable<Failure>'.
Types of parameters 'value' and 'value' are incompatible.
Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'.ts(2345)
It looks like something to do with how Describe
handles null
for some reason, which makes it impossible to use it with a generic. I'm not sure why that's happening, but if you can find a solution I'd be happy to merge a pull request.
This may be running into limitations in TypeScript.
Had a (somewhat) similar issue with Describe
and nullability recently:
type X = {
a: number;
};
const XStruct: s.Describe<X> = s.object({
a: s.number(),
});
// So far everything works as expected.
// Now let's assume we have to define a custom guard for X,
// because X might be defined in an external library,
// i.e. the library does not provide a superstruct struct for the static type.
const isX = (x: unknown): x is X => {
return 'a' in (x as X);
};
// Here we run into a compile error:
const XStructFromGuard: s.Describe<X> = s.define('X', isX);
// TS2322: Type 'Struct<X, null>' is not assignable to type 'Describe<X>'.
// Types of property 'schema' are incompatible.
// Type 'null' is not assignable to type '{ a: Describe<number>; }'.
Thanks for the great library!
I have stumbled on the following when I use use two objects in a union and using
Describe
for example:
throws:
I have created an example here of the issue. What is confusing for me is that there is no error when a number is added to the union
https://codesandbox.io/s/dreamy-ardinghelli-8e51j?file=/src/App.tsx:747-795