作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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' } });
我想我在这里遗漏了一些相当简单的东西,但希望能深入了解如何获得理想的行为(当我专门检索 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/
我有某种内存或 winsock 问题,只有在 Release模式下编译 c++ 代码时才会发生。 内存问题的证据: 通过注释掉两行代码,修复了之前未知的错误。这两行代码看似无害。它们是旧版本遗留下来的
我是一名优秀的程序员,十分优秀!