typescript :防止分配具有比目标界面中指定的更多属性的对象

标签 typescript

假设我有一个典型的“用户”对象,具有通常的用户名、电子邮件、密码等属性。我想创建和管理一个对象,该对象是此类用户的真正“子集”,并保证不包含密码。这是一个粗略的方法:

interface IUserSansPassword {
    username: string;
    email: string;
}

class UserSansPassword implements IUserSansPassword { ... }

interface IUser extends IUserSansPassword {
    password: string;
}

class User implements IUser { ... }

在尝试创建 IUserSansPassword 类型的对象时,我预计会出现以下错误:
const userSansPassword: UserSansPassword = new User(); // No TS Error †††

但是,我没有收到 TS 错误,因为令我惊讶的是,TS 并未禁止分配具有已建立的“额外”属性的对象。这是令人惊讶的,因为如果我尝试直接使用额外的属性进行定义,我会得到一个错误,如下所示:
const userSansPassword: IUserSansPassword = {
    username: 'jake',
    email: 'jake@snake.com',
    password: '' // TS Error ***
}

我的问题总结:
  • 为什么 TS 会这样?允许分配给具有多余属性的类型不是很糟糕(因此为什么会在上面的 *** 中出现错误)?
  • 是否有 TS 设置或技术可以让 TS 在上面的†††中出错?
  • 最佳答案

    这里的其他答案基本上是正确的:TypeScript 中的类型通常是开放/可扩展的,并且总是可以添加属性;也就是说,它们不是只允许存在已知属性的精确类型(如 microsoft/TypeScript#12936 中所要求的)。 TypeScript 通常并不真正支持精确类型,尽管它确实通过 excess property checks 将新创建的对象字面量的类型视为精确类型。 ,正如你所注意到的。
    如果你真的想禁止 TypeScript 中某个类型的特定属性键,可以通过将属性设为可选并将其类型设置为 never 来实现。或 undefined :

    interface IUserSansPassword {
      username: string;
      email: string;
      password?: never; // cannot have a password
    }
    
    declare class UserSansPassword implements IUserSansPassword {
      username: string;
      email: string;
      password?: never; // need to declare this also
    }
    
    现在UserSansPassword已知没有定义的 password属性(property)。当然现在以下是一个错误:
    interface IUser extends IUserSansPassword { // error! 
    // Types of property "password" are incompatible
      password: string;
    }
    
    您不能延长 IUserSansPassword通过添加密码... if A extends B那么您可以随时使用 A一个 B 的实例实例是预期的。你可以做的是扩展一个相关的类型,你原来的 IUserSansPassword ,可以使用 Omit helper type 计算:
    interface IUser extends Omit<IUserSansPassword, "password"> {
      password: string;
    }
    
    declare class User implements IUser {
      username: string;
      email: string;
      password: string;
    }
    
    然后以下是您期望的错误:
    const userSansPassword: UserSansPassword = new User();
    // error, mismatch on "password" prop
    
    好的,希望有帮助;祝你好运!
    Link to code

    关于 typescript :防止分配具有比目标界面中指定的更多属性的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57497299/

    相关文章:

    javascript - 更新 ngrx/store 中的对象

    typescript - 表示具有私有(private)构造函数的泛型类的类型

    typescript - 在 TypeScript 中编写通用克隆方法

    node.js - 如何在 typescript 中使用 yargs 解析命令行参数

    javascript - 如何使用几个 next.js 插件(typescript 和 stylus)

    typescript :声明返回类型取决于参数值?

    typescript - 在 Typescript 中解码 JWT 给出错误 "Object is possibly ' undefined”

    angular - 有没有办法在自动完成(Angular 4)中进行多项选择?

    javascript - 如何使用 typescript/javascript 正确解析 multipart/byteranges 响应?

    jquery - 使用 Moment.js 获取当年的第一天