Skip to content

Commit

Permalink
Improve typings in generics
Browse files Browse the repository at this point in the history
  • Loading branch information
colinhacks committed Mar 6, 2023
1 parent 942e2db commit b276d71
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 69 deletions.
10 changes: 4 additions & 6 deletions deno/lib/helpers/util.ts
Expand Up @@ -99,17 +99,15 @@ export namespace objectUtil {
[k in Exclude<keyof U, keyof V>]: U[k];
} & V;

type optionalKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? k : never;
}[keyof T];
// type optionalKeys<T extends object> = {
// [k in keyof T]: undefined extends T[k] ? k : never;
// }[keyof T];

type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];

export type addQuestionMarks<T extends object> = Partial<
Pick<T, optionalKeys<T>>
> &
export type addQuestionMarks<T extends object> = Partial<T> &
Pick<T, requiredKeys<T>>;

export type identity<T> = T;
Expand Down
53 changes: 25 additions & 28 deletions deno/lib/types.ts
Expand Up @@ -2131,44 +2131,41 @@ export type mergeTypes<A, B> = {
: never;
};

export type baseObjectOutputType<Shape extends ZodRawShape> =
objectUtil.flatten<
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_output"];
}>
>;

export type objectOutputType<
Shape extends ZodRawShape,
Catchall extends ZodTypeAny,
UnknownKeys extends UnknownKeysParam = UnknownKeysParam
> = (ZodTypeAny extends Catchall
? baseObjectOutputType<Shape> & Passthrough<UnknownKeys>
: baseObjectOutputType<Shape> & {
[k: string]: Catchall["_output"];
}) &
Passthrough<UnknownKeys>;

export type baseObjectInputType<Shape extends ZodRawShape> = objectUtil.flatten<
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_input"];
}>
>;
> = objectUtil.flatten<baseObjectOutputType<Shape>> &
CatchallOutput<Catchall> &
PassthroughType<UnknownKeys>;

export type Passthrough<UnknownKeys extends UnknownKeysParam> =
UnknownKeys extends "passthrough" ? { [k: string]: unknown } : unknown;
export type baseObjectOutputType<Shape extends ZodRawShape> =
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_output"];
}>;

export type objectInputType<
Shape extends ZodRawShape,
Catchall extends ZodTypeAny,
UnknownKeys extends UnknownKeysParam = UnknownKeysParam
> = ZodTypeAny extends Catchall
? baseObjectInputType<Shape> & Passthrough<UnknownKeys>
: objectUtil.flatten<
baseObjectInputType<Shape> & {
[k: string]: Catchall["_input"];
} & Passthrough<UnknownKeys>
>;
> = objectUtil.flatten<baseObjectInputType<Shape>> &
CatchallInput<Catchall> &
PassthroughType<UnknownKeys>;
export type baseObjectInputType<Shape extends ZodRawShape> =
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_input"];
}>;

export type CatchallOutput<T extends ZodTypeAny> = ZodTypeAny extends T
? unknown
: { [k: string]: T["_output"] };

export type CatchallInput<T extends ZodTypeAny> = ZodTypeAny extends T
? unknown
: { [k: string]: T["_input"] };

export type PassthroughType<T extends UnknownKeysParam> =
T extends "passthrough" ? { [k: string]: unknown } : unknown;

export type deoptional<T extends ZodTypeAny> = T extends ZodOptional<infer U>
? deoptional<U>
Expand Down
19 changes: 18 additions & 1 deletion playground.ts
@@ -1,3 +1,20 @@
import { z } from "./src";

z;
async function stripOuter<TData extends z.ZodTypeAny>(
schema: TData,
url: string
): Promise<TData["_output"]> {
const zStrippedResponse = z
.object({
topLevelKey: schema,
})
.transform((data) => {
return data.topLevelKey;
});

return fetch(url)
.then((response) => response.json())
.then((data) => zStrippedResponse.parse(data));
}

type asdf = Omit<{ a: string }, "b">;
10 changes: 4 additions & 6 deletions src/helpers/util.ts
Expand Up @@ -99,17 +99,15 @@ export namespace objectUtil {
[k in Exclude<keyof U, keyof V>]: U[k];
} & V;

type optionalKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? k : never;
}[keyof T];
// type optionalKeys<T extends object> = {
// [k in keyof T]: undefined extends T[k] ? k : never;
// }[keyof T];

type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];

export type addQuestionMarks<T extends object> = Partial<
Pick<T, optionalKeys<T>>
> &
export type addQuestionMarks<T extends object> = Partial<T> &
Pick<T, requiredKeys<T>>;

export type identity<T> = T;
Expand Down
53 changes: 25 additions & 28 deletions src/types.ts
Expand Up @@ -2131,44 +2131,41 @@ export type mergeTypes<A, B> = {
: never;
};

export type baseObjectOutputType<Shape extends ZodRawShape> =
objectUtil.flatten<
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_output"];
}>
>;

export type objectOutputType<
Shape extends ZodRawShape,
Catchall extends ZodTypeAny,
UnknownKeys extends UnknownKeysParam = UnknownKeysParam
> = (ZodTypeAny extends Catchall
? baseObjectOutputType<Shape> & Passthrough<UnknownKeys>
: baseObjectOutputType<Shape> & {
[k: string]: Catchall["_output"];
}) &
Passthrough<UnknownKeys>;

export type baseObjectInputType<Shape extends ZodRawShape> = objectUtil.flatten<
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_input"];
}>
>;
> = objectUtil.flatten<baseObjectOutputType<Shape>> &
CatchallOutput<Catchall> &
PassthroughType<UnknownKeys>;

export type Passthrough<UnknownKeys extends UnknownKeysParam> =
UnknownKeys extends "passthrough" ? { [k: string]: unknown } : unknown;
export type baseObjectOutputType<Shape extends ZodRawShape> =
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_output"];
}>;

export type objectInputType<
Shape extends ZodRawShape,
Catchall extends ZodTypeAny,
UnknownKeys extends UnknownKeysParam = UnknownKeysParam
> = ZodTypeAny extends Catchall
? baseObjectInputType<Shape> & Passthrough<UnknownKeys>
: objectUtil.flatten<
baseObjectInputType<Shape> & {
[k: string]: Catchall["_input"];
} & Passthrough<UnknownKeys>
>;
> = objectUtil.flatten<baseObjectInputType<Shape>> &
CatchallInput<Catchall> &
PassthroughType<UnknownKeys>;
export type baseObjectInputType<Shape extends ZodRawShape> =
objectUtil.addQuestionMarks<{
[k in keyof Shape]: Shape[k]["_input"];
}>;

export type CatchallOutput<T extends ZodTypeAny> = ZodTypeAny extends T
? unknown
: { [k: string]: T["_output"] };

export type CatchallInput<T extends ZodTypeAny> = ZodTypeAny extends T
? unknown
: { [k: string]: T["_input"] };

export type PassthroughType<T extends UnknownKeysParam> =
T extends "passthrough" ? { [k: string]: unknown } : unknown;

export type deoptional<T extends ZodTypeAny> = T extends ZodOptional<infer U>
? deoptional<U>
Expand Down

0 comments on commit b276d71

Please sign in to comment.