[英]How to replace properties using mapped types in Typescript
我有一个可以接收对象的Factory函数,如果该对象具有具有特定名称的属性,则工厂会将这些属性转换为方法。
如何使用映射的类型正确表示输出对象的类型?
例如,假设可转换属性为foo,bar和baz:
interface IFactoryConfig {
foo?: string;
bar?: string;
baz?: string;
}
替换属性为:
interface IFactoryResult {
foo(someParam: string): boolean;
bar(): number;
baz(otherParam: number): void;
}
如果输入的类型是
interface IInputObject {
baz: string;
notPredefined: string;
aNumber: number;
foo: string;
aMethod(): void;
}
工厂用方法替换baz和foo并返回:
interface IInputObject {
baz(otherParam: number): void;
notPredefined: string;
aNumber: number;
foo(someParam: string): boolean;
aMethod(): void;
}
我正在尝试使用映射类型来替换属性:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
interface IFactory {
<InputType extends IFactoryConfig, ResultType>(config: InputType): Omit<InputType, keyof IFactoryConfig> & Pick<IFactoryResult, ?>;
}
我不知道要放在Pick <>中以从IFactoryResult中选择也出现在InputType上的属性。
我们在这里只讨论类型级别的东西,而不是运行时行为。 您可以在映射类型内使用条件类型来执行检查。 这是一个通用的属性替换器:
type ReplaceProps<T, From, To> = { [K in keyof T]:
K extends keyof From ? T[K] extends From[K] ? K extends keyof To ? To[K]
: T[K] : T[K] : T[K]
}
我们的想法是,在任何财产T
,其键和值类型也发现,在From
和其键中找到To
将物业类型替换To
; 否则,它会独自留下财产。
然后,您可以像这样使用它:
type IInputObjectOut = ReplaceProps<IInputObject, IFactoryConfig, IFactoryResult>;
并检查IInputObjectOut
您可以看到它与所需的类型匹配:
type IInputObjectOut = {
baz: (otherParam: number) => void;
notPredefined: string;
aNumber: number;
foo: (someParam: string) => boolean;
aMethod: () => void;
}
我认为您可以像这样定义IFactory
类型,假设它应该是可调用的,并且其输入类型的行为类似于ReplaceProps
:
interface IFactory {
<T>(config: T): ReplaceProps<T, IFactoryConfig, IFactoryResult>;
}
declare const iFact: IFactory;
declare const input: IInputObject;
input.foo; // string
input.aNumber; // number
const output = iFact(input); // ReplaceProps<IInputObject, IFactoryConfig, IFactoryResult>;
output.foo("hey"); // boolean
output.aNumber; // number
那对你有用吗? 希望能帮助到你。 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.