summaryrefslogtreecommitdiff
path: root/packages/backend/src/misc
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2022-02-19 23:21:28 +0900
committerGitHub <noreply@github.com>2022-02-19 23:21:28 +0900
commitfd8f8162e186981ca2acf9d3b1caef523c748691 (patch)
tree676edf6a146b5835b8a591f4f00051999e356571 /packages/backend/src/misc
parentrefacator: fix typw (diff)
downloadmisskey-fd8f8162e186981ca2acf9d3b1caef523c748691.tar.gz
misskey-fd8f8162e186981ca2acf9d3b1caef523c748691.tar.bz2
misskey-fd8f8162e186981ca2acf9d3b1caef523c748691.zip
SchemaTypeの型計算量を削減 (#8332)
* schema typeの型計算量を削減 * reduce some type error * wip * fix * clean up * more shrink
Diffstat (limited to 'packages/backend/src/misc')
-rw-r--r--packages/backend/src/misc/schema.ts47
1 files changed, 15 insertions, 32 deletions
diff --git a/packages/backend/src/misc/schema.ts b/packages/backend/src/misc/schema.ts
index fbe5a1e421..5909969bbf 100644
--- a/packages/backend/src/misc/schema.ts
+++ b/packages/backend/src/misc/schema.ts
@@ -63,14 +63,7 @@ export const refs = {
Emoji: packedEmojiSchema,
};
-// Packed = SchemaTypeDef<typeof refs[x]>; とすると展開されてマウスホバー時に型表示が使い物にならなくなる
-// ObjType<r['properties']>を指定すると(なぜか)展開されずにPacked<'Hoge'>と表示される
-type PackedDef<r extends { properties?: Obj; oneOf?: ReadonlyArray<Schema>; allOf?: ReadonlyArray<Schema> }> =
- r['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<r['allOf']>> :
- r['oneOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<r['oneOf']> :
- r['properties'] extends Obj ? ObjType<r['properties'], any> :
- never;
-export type Packed<x extends keyof typeof refs> = PackedDef<typeof refs[x]>;
+export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;
type TypeStringef = 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'array' | 'object' | 'any';
type StringDefToType<T extends TypeStringef> =
@@ -107,31 +100,20 @@ export interface Schema extends OfSchema {
readonly minLength?: number;
}
-type OptionalPropertyNames<T extends Obj> = {
- [K in keyof T]: T[K]['optional'] extends true ? K : never
-}[keyof T];
-
-type NonOptionalPropertyNames<T extends Obj> = {
- [K in keyof T]: T[K]['optional'] extends false ? K : never
-}[keyof T];
-
-type DefaultPropertyNames<T extends Obj> = {
- [K in keyof T]: T[K]['default'] extends null ? K :
- T[K]['default'] extends string ? K :
- T[K]['default'] extends number ? K :
- T[K]['default'] extends boolean ? K :
- T[K]['default'] extends Record<string, unknown> ? K :
- never
-}[keyof T];
+type RequiredPropertyNames<s extends Obj> = {
+ [K in keyof s]:
+ // K is not optional
+ s[K]['optional'] extends false ? K :
+ // K has default value
+ s[K]['default'] extends null | string | number | boolean | Record<string, unknown> ? K : never
+}[keyof s];
export interface Obj { [key: string]: Schema; }
-export type ObjType<s extends Obj, RequiredProps extends ReadonlyArray<keyof s>> =
+export type ObjType<s extends Obj, RequiredProps extends keyof s> =
{ -readonly [P in keyof s]?: SchemaType<s[P]> } &
- { -readonly [P in RequiredProps[number]]: SchemaType<s[P]> } &
- { -readonly [P in OptionalPropertyNames<s>]?: SchemaType<s[P]> } &
- { -readonly [P in NonOptionalPropertyNames<s>]: SchemaType<s[P]> } &
- { -readonly [P in DefaultPropertyNames<s>]: SchemaType<s[P]> };
+ { -readonly [P in RequiredProps]: SchemaType<s[P]> } &
+ { -readonly [P in RequiredPropertyNames<s>]: SchemaType<s[P]> };
type NullOrUndefined<p extends Schema, T> =
p['nullable'] extends true
@@ -142,11 +124,12 @@ type NullOrUndefined<p extends Schema, T> =
? (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
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
// https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552
-// 単純にSchemaTypeDef<X>で判定するだけではダメ
+// To get union, we use `Foo extends any ? Hoge<Foo> : never`
type UnionSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? SchemaType<X> : never;
type ArrayUnion<T> = T extends any ? Array<T> : never;
@@ -163,7 +146,7 @@ export type SchemaTypeDef<p extends Schema> =
p['type'] extends 'boolean' ? boolean :
p['type'] extends 'object' ? (
p['ref'] extends keyof typeof refs ? Packed<p['ref']> :
- p['properties'] extends NonNullable<Obj> ? ObjType<p['properties'], NonNullable<p['required']>> :
+ p['properties'] extends NonNullable<Obj> ? ObjType<p['properties'], NonNullable<p['required']>[number]> :
p['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['anyOf']> & Partial<UnionToIntersection<UnionSchemaType<p['anyOf']>>> :
p['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> :
any