Fix #8535 Excessive stack ... 'SchemaTypeDef<?>' (#8547)

* Fix #8535 Excessive stack ... 'SchemaTypeDef<?>'

Co-authored-by: acid-chicken <root@acid-chicken.com>

* add comment

* clean up

Co-authored-by: acid-chicken <root@acid-chicken.com>
This commit is contained in:
tamaina 2022-04-27 10:49:00 +09:00 committed by GitHub
parent b9e3267198
commit 065324d30b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -98,6 +98,9 @@ export interface Schema extends OfSchema {
readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null; readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null;
readonly maxLength?: number; readonly maxLength?: number;
readonly minLength?: number; readonly minLength?: number;
readonly maximum?: number;
readonly minimum?: number;
readonly pattern?: string;
} }
type RequiredPropertyNames<s extends Obj> = { type RequiredPropertyNames<s extends Obj> = {
@ -105,24 +108,26 @@ type RequiredPropertyNames<s extends Obj> = {
// K is not optional // K is not optional
s[K]['optional'] extends false ? K : s[K]['optional'] extends false ? K :
// K has default value // K has default value
s[K]['default'] extends null | string | number | boolean | Record<string, unknown> ? K : never s[K]['default'] extends null | string | number | boolean | Record<string, unknown> ? K :
never
}[keyof s]; }[keyof s];
export interface Obj { [key: string]: Schema; } export type Obj = Record<string, Schema>;
// https://github.com/misskey-dev/misskey/issues/8535
// To avoid excessive stack depth error,
// deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it).
export type ObjType<s extends Obj, RequiredProps extends keyof s> = export type ObjType<s extends Obj, RequiredProps extends keyof s> =
{ -readonly [P in keyof s]?: SchemaType<s[P]> } & UnionToIntersection<
{ -readonly [P in RequiredProps]: SchemaType<s[P]> } & { -readonly [R in RequiredPropertyNames<s>]-?: SchemaType<s[R]> } &
{ -readonly [P in RequiredPropertyNames<s>]: SchemaType<s[P]> }; { -readonly [R in RequiredProps]-?: SchemaType<s[R]> } &
{ -readonly [P in keyof s]?: SchemaType<s[P]> }
>;
type NullOrUndefined<p extends Schema, T> = type NullOrUndefined<p extends Schema, T> =
p['nullable'] extends true | (p['nullable'] extends true ? null : never)
? p['optional'] extends true | (p['optional'] extends true ? undefined : never)
? (T | null | undefined) | T;
: (T | null)
: p['optional'] extends true
? (T | undefined)
: T;
// https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection // https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
// Get intersection from union // Get intersection from union
@ -139,9 +144,9 @@ export type SchemaTypeDef<p extends Schema> =
p['type'] extends 'number' ? number : p['type'] extends 'number' ? number :
p['type'] extends 'string' ? ( p['type'] extends 'string' ? (
p['enum'] extends readonly string[] ? p['enum'] extends readonly string[] ?
p['enum'][number] : p['enum'][number] :
p['format'] extends 'date-time' ? string : // Dateにする p['format'] extends 'date-time' ? string : // Dateにする
string string
) : ) :
p['type'] extends 'boolean' ? boolean : p['type'] extends 'boolean' ? boolean :
p['type'] extends 'object' ? ( p['type'] extends 'object' ? (