在以下代码中...
primesList
为什么在调用primesList
时将interface Options {
allowed?: string;
}
function test(options: Options) {
return options;
}
const options = {
allowed: 'allowed',
notAllowed: 'notAllowed',
};
test(options); // does not throw an error
添加到notAllowed
时不会在Typescript中引发错误?
我该怎么写,以免多余的属性?
编辑1 ...
如果我将Typescript重写为options
,可以使Typescript引发错误。
但是,因为我已指定函数中的options参数应该为Options类型,所以typescript不应该推断吗?
如果没有,打字稿尝试传递test(options)
时不应该抛出错误吗?
否则,这对于其他开发人员将自己的对象传递到const options: Options = {...};
函数中不是很有用。
编辑2 ...
我想要这样做的原因是我不想让开发人员拼写错误的属性。例如,我希望他们能够提供const object = {...};
属性,并禁止test
属性。当它们在include
函数中作为参数传递对象变量(而不是对象文字)时,使这种情况发生的唯一方法是在includes
接口{{1} }或类似的东西?
答案 0 :(得分:1)
我该怎么写,以免多余的属性?
不能。 Typescript继承了JavaScript的duck typing,并且鸭子还是鸭子,即使鸭子发出不同的羽毛也很容易。
或者换句话说:options
内部的对象是Options
对象,因为它具有Options
所需的所有属性(无)。
答案 1 :(得分:1)
问题在于TypeScript确实没有exact types,其中属性仅限于显式声明的属性。您需要的Excess property checking仅在使用新鲜对象文字的特定情况下发生。
尝试解决此问题的一种方法是使您的test()
函数具有通用性,使其在注意到额外属性的情况下无法编译。 linked duplicate question的答案说明了它是如何工作的。观察:
type Exactly<T, U> = T & Record<Exclude<keyof U, keyof T>, never>;
function test<T extends Exactly<Options, T>>(options: T) {
return options;
}
const okay = { allowed: "okay" };
test(okay); // no error
const excess = {
allowed: 'allowed',
notAllowed: 'notAllowed',
};
test(excess); // error
好的,希望能有所帮助;祝你好运!
答案 2 :(得分:0)
如果您要构建测试函数供其他开发人员稍后使用,则最好不要在参数类型输入中使用接口,因为除非将对象传递给test()函数之前将其键入,否则它将不起作用。最好的做法是使用可选参数:
function test(allowed?: string) {
return { allowed };
}
const options = {
allowed: 'allowed',
notAllowed: 'notAllowed',
};
test(); //works fine
test(options.allowed); //works fine
test(options.allowed, options.disallowed); //error