我对Typescript的类型系统有个问题。有人能帮我吗?
请看一下the demo。
type Props = { [key: string]: any };
type Config<P extends Props> = {
hint: string,
main: (p: P) => string
}
function createDemo<P extends Props>(config: Config<P>): (p: P) => void {
return (props: P) => {
document.body.innerHTML +=
`<div>[${config.hint} ${JSON.stringify(props)}] `
+ `${config.main(props)}</div>`;
};
}
const demo = createDemo({
hint: 'showing sum of two values',
main: ({ x, y }) => x + y
});
demo({ x: 11, y: 22 });
demo({ xx: 11, yy: 22 }); // why do I not get
// a Typescript compile-time
// error here?!?我预计最后一条语句demo({ xx: 11, yy: 22 })会产生编译时错误。但typescript转译器似乎认为这没问题。为什么?如何才能将demo更改为类型安全(意思是:使用最后一条语句来导致编译时错误)?
编辑:1小时后
如果我给你看这个代码片段,它的行为完全符合我的预期(至少在tsconfig.json配置正确的情况下),可能会有一点帮助:
function createDemo<P>(action: ((data: P) => void)) {
return (data: P) => {
action(data);
};
}
const demo = createDemo((data: { x: number; y: number }) => {
document.body.innerText += JSON.stringify(data) + "\n";
});
demo({ x: 11, y: 22 });
demo({ xx: 11, yy: 22 }); // <- ERROR!!!编辑-2小时后
好的,谢谢,在阅读了下面的答案后,我了解到如果我在"createDemo“调用中添加实际的类型签名,事情就会按照我期望的方式工作。
尽管如此,坦率地说,我仍然不完全理解为什么
const f = ({ x, y }) => ...;
被插入为
const f = ({ x, y }: { x: any, y: any}) => ...
而在上面的第一个示例中,main函数的类型签名
main: ({ x, y }) => ...
将被插入为
main: (p: {}) => ...
而不是
main: ({ x, y }: { x: any, y: any }) => ...
发布于 2018-06-02 06:50:24
看看你的代码,给你一点建议。我不认为你需要P扩展道具。问题是,this is Props是一个字符串和传递数字的字典。
至于你当前的演示不能工作,这是因为createDemo中的main方法没有类型签名,因为它的参数只需添加一个就可以解决这个问题,参数通常默认为any。
const demo = createDemo({
hint: 'showing sum of two values',
main: ({ x, y }:{x:number, y:number}) => ""+x + y
});注意,添加""+x+y是因为您传递了数字,而main的结果应该是一个字符串。
发布于 2018-06-02 06:58:30
函数createDemo返回类型为({ [key: string]: any }) => void的函数,因此这就是demo的类型。因此,demo接受任何字符串作为键、任何类型作为值的对象。
例如,您可以向createDemo提供一个类型参数来修复此问题:
const demo = createDemo<{x: any, y: any}>({
hint: 'showing sum of two values',
main: ({ x, y }) => x + y
});https://stackoverflow.com/questions/50651790
复制相似问题