chore: update the types to inference better

This commit is contained in:
BluJ
2023-02-14 14:46:23 -07:00
parent 757033d503
commit ef41ce7762
5 changed files with 33 additions and 32 deletions

View File

@@ -7,9 +7,10 @@ export class Config<A extends ConfigSpec> extends IBuilder<A> {
return new Config({}); return new Config({});
} }
static withValue<K extends string, B extends ValueSpec>(key: K, value: Value<B>) { static withValue<K extends string, B extends ValueSpec>(key: K, value: Value<B>) {
return new Config({ return Config.empty().withValue(key, value);
[key]: value.build(), }
} as { [key in K]: B }); static addValue<K extends string, B extends ValueSpec>(key: K, value: Value<B>) {
return Config.empty().withValue(key, value);
} }
static of<B extends { [key: string]: Value<C> }, C extends ValueSpec>(spec: B) { static of<B extends { [key: string]: Value<C> }, C extends ValueSpec>(spec: B) {

View File

@@ -1,4 +1,4 @@
import { IBuilder } from "./builder.ts"; import { BuilderExtract, IBuilder } from "./builder.ts";
import { Config } from "./config.ts"; import { Config } from "./config.ts";
import { Default, NullableDefault, NumberSpec, StringSpec } from "./value.ts"; import { Default, NullableDefault, NumberSpec, StringSpec } from "./value.ts";
import { Description } from "./value.ts"; import { Description } from "./value.ts";
@@ -50,19 +50,18 @@ export class List<A extends ValueSpecList> extends IBuilder<A> {
} }
static objectV< static objectV<
A extends Description & A extends Description &
NullableDefault<Record<string, unknown>[]> & { Default<Record<string, unknown>[]> & {
range: string; range: string;
spec: { spec: {
spec: Config<B>; spec: Config<ConfigSpec>;
"display-as": null | string; "display-as": null | string;
"unique-by": null | UniqueBy; "unique-by": null | UniqueBy;
}; };
}, }
B extends ConfigSpec
>(a: A) { >(a: A) {
const { spec: previousSpec, ...rest } = a; const { spec: previousSpec, ...rest } = a;
const { spec: previousSpecSpec, ...restSpec } = previousSpec; const { spec: previousSpecSpec, ...restSpec } = previousSpec;
const specSpec = previousSpecSpec.build(); const specSpec = previousSpecSpec.build() as BuilderExtract<A["spec"]["spec"]>;
const spec = { const spec = {
...restSpec, ...restSpec,
spec: specSpec, spec: specSpec,
@@ -75,7 +74,7 @@ export class List<A extends ValueSpecList> extends IBuilder<A> {
type: "list" as const, type: "list" as const,
subtype: "object" as const, subtype: "object" as const,
...value, ...value,
} as ValueSpecListOf<"object">); });
} }
static union< static union<
A extends Description & A extends Description &
@@ -90,17 +89,16 @@ export class List<A extends ValueSpecList> extends IBuilder<A> {
[key: string]: string; [key: string]: string;
}; };
}; };
variants: Variants<B>; variants: Variants<{ [key: string]: ConfigSpec }>;
"display-as": null | string; "display-as": null | string;
"unique-by": UniqueBy; "unique-by": UniqueBy;
default: string; default: string;
}; };
}, }
B extends { [key: string]: ConfigSpec }
>(a: A) { >(a: A) {
const { spec: previousSpec, ...rest } = a; const { spec: previousSpec, ...rest } = a;
const { variants: previousVariants, ...restSpec } = previousSpec; const { variants: previousVariants, ...restSpec } = previousSpec;
const variants = previousVariants.build(); const variants = previousVariants.build() as BuilderExtract<A["spec"]["variants"]>;
const spec = { const spec = {
...restSpec, ...restSpec,
variants, variants,

View File

@@ -1,4 +1,4 @@
import { IBuilder } from "./builder.ts"; import { BuilderExtract, IBuilder } from "./builder.ts";
import { Config } from "./config.ts"; import { Config } from "./config.ts";
import { List } from "./list.ts"; import { List } from "./list.ts";
import { Pointer } from "./pointer.ts"; import { Pointer } from "./pointer.ts";
@@ -9,6 +9,7 @@ import {
ValueSpec, ValueSpec,
ValueSpecList, ValueSpecList,
ValueSpecNumber, ValueSpecNumber,
ValueSpecObject,
ValueSpecString, ValueSpecString,
} from "../types/config-types.ts"; } from "../types/config-types.ts";
@@ -80,18 +81,20 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
...a, ...a,
}); });
} }
static objectV< static object<
A extends Description & A extends {
NullableDefault<{ [k: string]: unknown }> & { name: string;
"display-as": null | string; description: string | null;
"unique-by": null | string; warning: string | null;
spec: Config<B>; default: null | { [k: string]: unknown };
"value-names": Record<string, string>; "display-as": null | string;
}, "unique-by": null | string;
B extends ConfigSpec spec: Config<ConfigSpec>;
"value-names": Record<string, string>;
}
>(a: A) { >(a: A) {
const { spec: previousSpec, ...rest } = a; const { spec: previousSpec, ...rest } = a;
const spec = previousSpec.build(); const spec = previousSpec.build() as BuilderExtract<A["spec"]>;
return new Value({ return new Value({
type: "object" as const, type: "object" as const,
...rest, ...rest,
@@ -110,14 +113,13 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
[key: string]: string; [key: string]: string;
}; };
}; };
variants: Variants<B>; variants: Variants<{ [key: string]: ConfigSpec }>;
"display-as": string | null; "display-as": string | null;
"unique-by": UniqueBy; "unique-by": UniqueBy;
}, }
B extends { [key: string]: ConfigSpec }
>(a: A) { >(a: A) {
const { variants: previousVariants, ...rest } = a; const { variants: previousVariants, ...rest } = a;
const variants = previousVariants.build(); const variants = previousVariants.build() as BuilderExtract<A["variants"]>;
return new Value({ return new Value({
type: "union" as const, type: "union" as const,
...rest, ...rest,
@@ -128,7 +130,7 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
static pointer<A extends ValueSpec>(a: Pointer<A>) { static pointer<A extends ValueSpec>(a: Pointer<A>) {
return new Value(a.build()); return new Value(a.build());
} }
static list<A extends List<B>, B extends ValueSpecList>(a: A) { static list<A extends List<ValueSpecList>>(a: A) {
return new Value(a.build()); return new Value(a.build());
} }
} }

View File

@@ -135,7 +135,7 @@ export interface ListValueSpecEnum {
export interface ListValueSpecObject { export interface ListValueSpecObject {
spec: ConfigSpec; // this is a mapped type of the config object at this level, replacing the object's values with specs on those values spec: ConfigSpec; // this is a mapped type of the config object at this level, replacing the object's values with specs on those values
"unique-by": UniqueBy; // indicates whether duplicates can be permitted in the list "unique-by": UniqueBy; // indicates whether duplicates can be permitted in the list
"display-as"?: string; // this should be a handlebars template which can make use of the entire config which corresponds to 'spec' "display-as"?: null | string; // this should be a handlebars template which can make use of the entire config which corresponds to 'spec'
} }
export type UniqueBy = export type UniqueBy =

View File

@@ -52,7 +52,7 @@ type GuardList<A> =
// prettier-ignore // prettier-ignore
// deno-fmt-ignore // deno-fmt-ignore
type GuardPointer<A> = type GuardPointer<A> =
A extends {readonly type:TypePointer} ? {_UNKNOWN: "Pointer"} : A extends {readonly type:TypePointer} ? (string | null) :
unknown unknown
// prettier-ignore // prettier-ignore
// deno-fmt-ignore // deno-fmt-ignore