【发布时间】:2022-11-27 08:33:55
【问题描述】:
鉴于我有一个类似的界面:
export interface IHasIO {
inputs: {
[key: string]: string
},
outputs: {
[key: string]: string
}
}
我想创建一个函数,将其作为通用接口的实现,并确保其中一个输出键作为参数传递。
所以下面的类型定义会理想地创建一个这样的函数:
// extract the outputs property by indexing it.
export type Outputs<T extends IHasIO> = T['outputs'];
// only allow a key of one of the outputs to be the function parameter by using keyof.
export type writeToOutput<T extends IHasIO> = (param: keyof Outputs<T>) => void;
但是,如果我创建一个实现该接口的值,并将其用作通用 arg,则参数选项不受限制:
const instance: IHasIO = {
inputs: {},
outputs: {
a: 'someValue',
b: 'someOtherVal'
}
}
// create a dummy fn
const fn: writeToOutput<typeof instance> = (param) => {
}
// this should not work, as `c` is not one of the output keys, but it does work, as it passes the typescript linting errors
fn("c");
// only these should work:
fn("a");
fn("b";
我究竟做错了什么?
【问题讨论】:
-
通过将
instance的类型显式注释为IHasIO,您已经告诉编译器忘记任何比这更具体的内容。你应该放弃注解,让编译器推断它的类型;如果您关心确保它可分配给IHasIO,您可以使用 TS4.9+ 中的satisfies运算符,如in this playground link 所示。这是否完全解决了您的问题?如果是这样,我可以写一个答案来解释;如果没有,我错过了什么? (如果您回复,请通过@jcalz 联系我) -
@jcalz 是的,这似乎可以解决问题!
标签: typescript