限制Typescript对象实例化的属性

时间:2018-10-26 23:02:18

标签: javascript json angular typescript

我知道,article可以将类型良好的JSON轻松分配给对象。例如,使用以下类:

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

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

如果我有一个JSON格式的变量jsonUser

const jsonUser = {
    username: bob,
};

那我可以轻松地说:

user: User = <User>jsonUser;

我的问题是,如果可能的话,如何编写一个类,这限制了该类可以具有的属性。例如:

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

我上面定义的User类中没有电子邮件。当前,它允许将email作为属性分配给类型为User的变量。我希望它抛出一个错误或不分配它。

1 个答案:

答案 0 :(得分:0)

我认为这是不可能的,但是我在功能请求中找到了this interesting post,用于TypeScript中的确切类型。

基本上,您可以这样做:

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

最后的分配给我以下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; }'.

不是最直观的消息,但是它可以完成工作。

该解决方案的信用转到GitHub上的Rafał Łużyński (mindbrave)