-
-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
Hey there again, sorry that I keep digging up weird stuff :)
I have created a constructed type with
const stringOrObjectWithKey = string.construct(
(arg: { key: string } | string) =>
typeof arg === "string" ? [arg] : [arg.key]
);and I can call that just fine like
stringOrObjectWithKey("asd");
stringOrObjectWithKey({ key: "asd" });
now, when I chain that like
const withMin = stringOrObjectWithKey.min(1);I lose the ability to call it with the overload:
withMin("asd");
// Argument of type '{ key: string; }' is not assignable to parameter of type 'string'.ts(2345)
withMin({ key: "asd" });Looking at the types, I don't really see what is wrong there - and to be honest, these types are quite complicated to get started with so I'm a bit hesitant to do a PR on this.
I have, though, created a type test for this that you can use to verify this behaviour:
CodeSandBox
I hope that helps to pinpoint it down.
Please don't hesitate to contact me if I can help any further 🙂
/*eslint-disable @typescript-eslint/no-unused-vars */
import Schema, { string } from "computed-types";
import { SchemaResolveType, SchemaInput } from "computed-types/lib/schema/io";
function expectType<T>(t: T) {
return t;
}
function expectAssignable<Subtype, _Type extends Subtype>() {}
const stringOrObjectWithKey = string.construct(
(arg: { key: string } | string) =>
typeof arg === "string" ? [arg] : [arg.key]
);
stringOrObjectWithKey("asd");
stringOrObjectWithKey({ key: "asd" });
expectType<(v: string | { key: string }) => string>(stringOrObjectWithKey);
expectAssignable<
string | { key: string },
SchemaInput<typeof stringOrObjectWithKey>
>();
expectAssignable<
SchemaInput<typeof stringOrObjectWithKey>,
string | { key: string }
>();
const destructed = stringOrObjectWithKey.destruct();
destructed("asd");
destructed({ key: "asd" });
expectType<(v: string | { key: string }) => [any, string?]>(destructed);
// second signature missing here
expectType<(v: string) => [any, string?]>(destructed);
expectAssignable<string | { key: string }, SchemaInput<typeof destructed>>();
expectAssignable<SchemaInput<typeof destructed>, string | { key: string }>();
expectAssignable<[any, string?], SchemaResolveType<typeof destructed>>();
expectAssignable<SchemaResolveType<typeof destructed>, [any, string?]>();
const withMin = stringOrObjectWithKey.min(1);
withMin("asd");
withMin({ key: "asd" });
expectType<(v: string | { key: string }) => string>(withMin);
// second signature missing here
expectType<(v: string) => string>(withMin);
expectAssignable<string | { key: string }, SchemaInput<typeof withMin>>();
expectAssignable<SchemaInput<typeof withMin>, string | { key: string }>();
expectAssignable<string, SchemaResolveType<typeof withMin>>();
expectAssignable<SchemaResolveType<typeof withMin>, string>();
const inSchema = Schema({ test: stringOrObjectWithKey });
inSchema({ test: "asd" });
inSchema({ test: { key: "asd" } });
expectType<(v: { test: string | { key: string } }) => { test: string }>(
inSchema
);
expectAssignable<
{ test: string | { key: string } },
SchemaInput<typeof inSchema>
>();
expectAssignable<
SchemaInput<typeof inSchema>,
{ test: string | { key: string } }
>();
const destructedSchema = inSchema.destruct();
destructedSchema({ test: "asd" });
destructedSchema({ test: { key: "asd" } });
expectType<(v: { test: string | { key: string } }) => [any, { test: string }?]>(
destructedSchema
);
const mergedSchema = Schema.merge({ other: string.optional() }, inSchema);
mergedSchema({ test: "asd" });
mergedSchema({ test: { key: "asd" } });
expectType<(v: { test: string | { key: string } }) => { test: string }>(
mergedSchema
);
expectAssignable<
{ test: string | { key: string } },
SchemaInput<typeof mergedSchema>
>();
expectAssignable<
SchemaInput<typeof mergedSchema>,
{ test: string | { key: string } }
>();
const mergedDestructedSchema = mergedSchema.destruct();
mergedDestructedSchema({ test: "asd" });
mergedDestructedSchema({ test: { key: "asd" } });
expectType<(v: { test: string | { key: string } }) => [any, { test: string }?]>(
mergedDestructedSchema
);Metadata
Metadata
Assignees
Labels
No labels