typescript - 打字稿在其键之一中从对象推断信息
问题描述
有
const a = {
propOne: {
methodOne(arg1, arg2: number) {
console.info('hello...')
}
},
proptwo: {
b(fn, arg2) {
fn('methodOne', 'hello') // Error
fn('methodOne', 1) // OK
}
}
}
我试图在我的 b 方法中尝试使用 fn 时获得类型 Error 和 Intelisense 的情况下使这个实现工作。所以基本上 fn 第一个参数是 propOne 的键之一,而 fn 第二个参数是基于你选择的方法。由于在示例中我选择了带有“methodOne”的 fn,因此第二个参数被推断为 number,因为 methodOne 的 arg2 是 number 类型。
如果我为 propOne 方法编写类型,我就能完成这项工作,但我想知道是否有更好的方法来解决这个问题。
解决方案
你可以让它大部分工作,除了我认为我们稍后会解决的错误。
第一个问题是我们需要使用一个函数来帮助进行推理。简单变量的类型可以从初始化表达式推断或在类型注释中指定,对于更复杂的行为,我们需要使用函数的推断行为。
我们将使用两个类型参数,一个 forpropOne
和一个 for propTwo
(我已将其重命名为actions
,mutations
正如我们在 twitter 上讨论的那样,原来的名称只是 Vue store props 的替身)
一旦我们捕获了类型参数,只需将类型参数actions
转换为函数的合适参数即可
type Func = (...a: any[]) => void;
type SkipFirstParameter<T extends Func> = T extends (a: any, ... r: infer P) => any ? P : [];
type Actions<M extends Record<string, Func>> = <MK extends keyof M>(mutation: MK, ...a: SkipFirstParameter<M[MK]>) => void
function create<T, M extends Record<string, Func>, A extends Record<string, (f: Actions<M>, ...a: any[]) => void>>(o: {
mutations: M
actions: A
}) {
return o
}
const a = create({
mutations: {
methodOne: (arg1: number, arg2: number) => {
console.info('hello...')
},
},
actions: {
b: (fn, arg2: number) => {
fn("methodOne", arg2)
fn("methodOne", "arg2")
}
}
});
你会注意到我切换到箭头函数,而不是速记语法或function
表达式。这是因为推理在箭头函数和其他函数之间的行为不同。我相信这是一个编译器错误和字段之一,但如果我们使用函数语法的方法M
将被推断为unknown
. 这可能与 TS 尝试推断this
此类函数的方式有关,但行为上的差异可能是一个错误。
推荐阅读
- javascript - 了解 jQuery 的实现——jQuery 对象是如何创建的?
- c - 在 2GB 范围内分配内存
- javascript - 在用户脚本中编辑音频元素音量
- html - 如何创建没有文本的 3 色列?
- javascript - 试图在反应中将父状态传递给子组件
- python - Pandas CSV 到 Django 响应
- git - 在提交时强制提交有额外的父母
- spring - spring批处理服务层中的nullpointer异常未注入
- azure-devops - 警告 CS0618:“ResourceManager.ResourceSets”已过时:“改为调用 InternalGetResourceSet”
- git - 需要为 yarn add jest 提供密码