如何在 Typescript 中使用映射类型替换属性
How to replace properties using mapped types in Typescript
我有一个接收对象的工厂函数,如果该对象具有特定名称的属性,工厂会将这些属性转换为方法。
如何使用映射类型来正确表示输出对象的类型?
例如,假设可转换属性为 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;
}
工厂用methods替换baz和foo returns:
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, ?>;
}
我不知道要从 IFactoryResult 中选择也出现在 InputType 上的属性的 Pick<> 中要放什么。
我们这里只讨论类型级的东西,而不是 运行 时间行为。您可以在映射类型中使用 conditional types 来执行检查。这是一个通用的 属性 替换器:
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
这对你有用吗?希望能帮助到你。祝你好运!
我有一个接收对象的工厂函数,如果该对象具有特定名称的属性,工厂会将这些属性转换为方法。
如何使用映射类型来正确表示输出对象的类型?
例如,假设可转换属性为 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;
}
工厂用methods替换baz和foo returns:
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, ?>;
}
我不知道要从 IFactoryResult 中选择也出现在 InputType 上的属性的 Pick<> 中要放什么。
我们这里只讨论类型级的东西,而不是 运行 时间行为。您可以在映射类型中使用 conditional types 来执行检查。这是一个通用的 属性 替换器:
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
这对你有用吗?希望能帮助到你。祝你好运!