gpt4 book ai didi

javascript - typescript 神秘的十字路口

转载 作者:行者123 更新时间:2023-11-30 11:08:30 27 4
gpt4 key购买 nike

TLDR:Playground Repro

在我的应用程序中,我定义了多个表单模块,大致如下:

const firstModule = {
name: 'firstModule',
mutation: () => {
return (opts: {variables: {firstModuleArg: string}}) => {}
}
}

const secondModule = {
name: 'secondModule',
mutation: () => {
return (opts: {variables: {secondModuleArg: number}}) => {}
}
}

如您所见,每个变异函数都会返回一个需要特定形状的变量字段的函数。

直接使用每个模块就可以了:

firstModule.mutation()({ variables: { firstModuleArg: 'test' } }); => ok

secondModule.mutation()({ variables: { secondModuleArg: 123 } }); => ok

但是,我还创建了这些表单的中央注册表,以便我可以从其他地方查找它们,如下所示:

const forms = {
firstModule,
secondModule
}


const getFormConfig = (root: 'firstModule' | 'secondModule') => {
const rootObj = forms[root];

return rootObj;
}

这就是问题所在。当我尝试引用组合表单对象的单个成员时,Typescript 似乎自动创建了 variables 字段的交集并抛出以下错误:

const { mutation: firstModuleMutation } = getFormConfig('firstModule');

firstModuleMutation()({ variables: { firstModuleArg: '1234' } });

Typescript Error

我想我在这里遗漏了一些相当简单的东西,但希望能深入了解如何获得理想的行为(当我专门检索 firstModule 时,我只希望它验证该模块的变量字段)。如果我可以提供任何其他信息,请告诉我。

谢谢!

最佳答案

当以这种方式定义函数时,TypeScript 会失去模块名称和变异返回类型之间的关系。

您可以使用函数重载或使用类型参数定义您的函数。由于已经提供了第一种解决方案,让我介绍第二种方法。它的优点是可以无限扩展。如果您决定扩展您的模型,它就会正常工作,而对于重载,您必须在每次模型更改时更新它们。

我们首先需要一些常用的助手。

type ValueOf<T> = T[keyof T];
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;

你的领域模型:

/**
* Type aliases.
*/
type Forms = typeof forms;
type Module = ValueOf<Forms>;

/**
* The return type for `getFormConfig`.
*/
type TransformedModule<T extends Module> = Overwrite<T, { mutation: ReturnType<T['mutation']> }>;

最终解决方案:

export function getFormConfig<K extends keyof Forms>(arg: K) {
const module = forms[arg];

return ({ ...module, mutation: module.mutation() }) as TransformedModule<Forms[K]>;
}

用法:

getFormConfig('firstModule').mutation({ variables: { firstModuleArg: 'foo' } })
getFormConfig('secondModule').mutation({ variables: { secondModuleArg: 42 } });

关于javascript - typescript 神秘的十字路口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54714232/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com