简体   繁体   English

限制Typescript对象实例化的属性

[英]Limit properties on instantiation of Typescript object

I know per this article that well typed JSON can easily be assigned to an object. 我从这篇文章中知道,可以将类型良好的JSON轻松分配给一个对象。 For example with the class: 例如与类:

export class User {
    id?: number;
    username: string;

    constructor(username: string) {
        this.username = username;
    }
}

If I had a JSON formatted variable jsonUser : 如果我有JSON格式的变量jsonUser

const jsonUser = {
    username: bob,
};

Then I could easily say: 然后我可以轻松地说:

user: User = <User>jsonUser;

The question I have is how do I write a class, if possible, which limits the properties that class can have. 我的问题是,如果可能的话,如何编写一个类,这限制了该类可以具有的属性。 For example: 例如:

const jsonUser = {
    username: bob,
    email: bob@bob.bob
};

My User class as defined above does not have email in it. 上面定义的“我的User类中没有电子邮件。 Currently, it allows email to be assigned as a property to my variable of type User . 目前,它允许将email作为属性分配给类型为User我的变量。 I'd rather it throw an error or not assign it. 我希望它抛出一个错误或不分配它。

I thought this wouldn't be possible, but I found this interesting post in a feature request for exact types in TypeScript. 我以为不可能,但是我在功能请求中找到了这个有趣的帖子 ,要求TypeScript中的确切类型。

Essentially you can do this: 本质上,您可以执行以下操作:

export class User {
    id?: number;
    username: string;

    constructor(username: string) {
        this.username = username;
    }
}

type Exact<A extends object> = A & {key: keyof A};

const jsonUser = {
    username: 'bob',
};

const jsonUser2 = {
    username: 'bob',
    id: 2
};

const jsonUser3 = {
    username: 'bob',
    email: 'bob@bob.bob'
};

const user: User = jsonUser as Exact<User>; // OK
const user2: User = jsonUser2 as Exact<User>; // OK
const user3: User = jsonUser3 as Exact<User>; // TypeScript error

The final assignment gives me the following TypeScript error: 最后的分配给我以下TypeScript错误:

Conversion of type '{ username: string; email: string; }' to type 'Exact<User>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '{ username: string; email: string; }' is not comparable to type '{ key: "id" | "username"; }'.
    Property 'key' is missing in type '{ username: string; email: string; }'.

Not the most intuitive message but it does the job. 不是最直观的消息,但它可以完成任务。

Credit for the solution goes to Rafał Łużyński (mindbrave) on GitHub. 该解决方案归功于 GitHub上的RafałŁużyński(mindbrave)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM