当接口中的所有属性都是可选的时,为什么在 Typescript 中允许多余的属性?

nra*_*ter 0 typescript

在以下代码中...

interface Options {
  allowed?: string;
}

function test(options: Options) {
  return options;
}

const options = {
  allowed: 'allowed',
  notAllowed: 'notAllowed',
};

test(options); // does not throw an error
Run Code Online (Sandbox Code Playgroud)

为什么在调用时添加notAllowedoptions不在 Typescript 中抛出错误test(options)

我怎样才能写这个,这样多余的属性就被禁止了?

编辑 1...

如果我将 Typescript 重写为const options: Options = {...};.

但是,打字稿不应该推断出这一点,因为我已经指定函数中的选项参数应该是选项类型吗?

如果没有,在尝试传入时打字稿不应该抛出错误const object = {...};吗?

否则,这对于其他开发人员将他们自己的对象传递到test函数中不是很有用。

编辑 2...

我想要这个的原因是为了我不希望开发商拼错属性的选项包。例如,我希望他们能够提供一个include属性并禁止该includes属性。当他们将对象变量(而不是对象文字)作为test函数中的参数传递时,实现这一点的唯一方法是在Options接口上声明一个属性includes?: null;或类似的东西吗?

jca*_*alz 5

问题是 TypeScript 并没有真正的确切类型,其中属性仅限于显式声明的类型。 多余的属性检查,这是您想要的,仅在您使用新对象文字的特定情况下发生。

尝试解决此问题的一种方法是使您的test()函数通用,如果它注意到额外的属性则无法编译。链接重复问题的答案解释了这是如何工作的。观察:

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
Run Code Online (Sandbox Code Playgroud)

好的,希望有帮助;祝你好运!

代码链接