繁体   English   中英

如何使用Typescript中的映射类型替换属性

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM