网站搜索

Typescript:为什么 Partial 接口不接受额外的字段?


interface User {
  name: string;
  age: number;  
}

let user: Partial<User> = {name: 'John', address: '123 Main st.'}

所以 TypeScript 会抱怨 address 在接口 User 中不存在。我的理解是,只要 Partial<User> 是右侧对象的子集,它应该是一个有效的强制转换。如何正确理解这一点?

答案#1

它被称为超额财产检查

摘自 TypeScript 文档 (https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks):

... TypeScript 认为这段代码可能有一个错误。对象字面量在被赋值给其他变量或作为参数传递时,会受到特殊处理并进行多余属性检查。如果对象字面量有任何目标类型没有的属性,你会收到一个错误。

绕过这些检查实际上非常简单。最简单的方法就是使用类型断言:

答案#2

@ABOS

这里 Partial<User> 为你所做的是将 User 接口的属性设为可选。

类似于这个,

interface User {
   name?: string;
   age?: number;
}

我认为你真正想做的是进一步扩展你的用户界面,

interface User {
    name: string;
    age: number;
}


interface Mod extends User {
    address: string;
}

// this here then makes age from the user interface optional but also allows 
// you to now have the address property.

let user: Partial<Mod> = {name: "John", address: "123 Main st."};

或者你可以通过在类中实现你的接口来使它更健壮,就像这样。

class Users implements Mod {
    address: string;
    name: string;
    age: number;

    // we can make the address and age defaulted values if not provided
    constructor(name: string, address: string = "", age: number = 0) {
        this.name = name;
        this.address = address;
        this.age = age;
    }
}

let user: Mod = new Users("John");

console.log(user.name);     // "John"
console.log(user.address);  // ""
console.log(user.age);      // 0