構建一個表單配置構建器,想要動態推斷型別,這里是最小的復制代碼
interface Meta {
optional: boolean
}
class Base<Type = any> {
readonly _type!: Type
baseMeta: Meta
constructor() {
this.baseMeta = {
optional: false,
}
}
optional() {
this.baseMeta.optional = true
return this;
}
}
class FieldText extends Base<string> {
}
class FieldNumber extends Base<number> {
}
class Field {
static text() {
return new FieldText();
}
static number() {
return new FieldNumber();
}
}
const fields = {
fieldText: Field.text(),
fieldNumber: Field.number(),
fieldTextOptional: Field.text().optional(),
fieldNumberOptional: Field.number().optional(),
}
給定上面的代碼,我想實作以下型別之一,不管是哪一個
type ExpectedType = {
fieldText: string;
fieldNumber: number;
fieldTextOptional: number | undefined;
fieldNumberOptional: number | undefined;
}
也不錯
type ExpectedTypeWithOptionalKeys = {
fieldText: string;
fieldNumber: number;
fieldTextOptional?: number;
fieldNumberOptional?: number;
}
我已經開始推斷型別,但無法弄清楚為什么不考慮可選屬性
type ExtractFieldType<O, T> = O extends true ? T | undefined : T;
type SchemaType<T extends Record<string, Base>> = {
[Property in keyof T]: ExtractFieldType<T[Property]['baseMeta']['optional'], T[Property]['_type']>;
};
type Schema = SchemaType<typeof fields>;
type Schema結果是:
type Schema = {
fieldText: string;
fieldNumber: number;
fieldTextOptional: string;
fieldNumberOptional: number;
}
這O extends true ? T | undefined : T總是回傳 T,不考慮 optional 的實際值
uj5u.com熱心網友回復:
optionalin的型別Meta總是. 您需要將值存盤在泛型中以供以后使用: boolean
interface Meta<Optional extends boolean> {
optional: Optional;
}
class Base<Type = any, Optional extends boolean = false> {
readonly _type!: Type
baseMeta: Meta<Optional>
constructor() {
this.baseMeta = {
optional: false as Optional,
}
}
optional(): Base<Type, true> {
this.baseMeta.optional = true as Optional; // needs unsafe assert, or alternatively //@ts-ignore
return this as Base<Type, true>;
}
}
然后,當您使用 更改它時optional,欺騙 TypeScript 使其相信您正在回傳Base<Type, true>。
你只需要改變它。您的原始解決方案現在有效。
解決評論中的后續問題:
optional<T extends boolean = true>(value: T = true): Base<Type, T> {
this.baseMeta.optional = value as Optional;
return this as Base<Type, T>;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/505113.html
標籤:javascript 打字稿
