首页 > 解决方案 > Typescript 通过带有类型检查的构造函数传递字段

问题描述

我正在尝试通过构造函数的对象传递字段对象:

new Alloy({ name: "foo" })

问题是未检查类型:

export class Alloy {

    name!: string

    constructor(data: Partial<Alloy>) {
        Object.assign<Alloy, Alloy>(this, {
            name: data.name!
        });
    }
}

例如,看我的第二个测试 ( is mandatory) 不会抛出错误,它应该是:

import { Alloy } from "./Alloy"

describe("Alloy", () => {

    const defaultParams = {
        name: "Foo bar"
    }

    describe("has a name", () => {
        test("is a string", async () => {
            const alloy = new Alloy({ ...defaultParams, name: "Foo bar" })

            expect(alloy.name).toEqual("Foo bar")
            expect(typeof alloy.name === "string").toBeTruthy()
        })

        // this test is failing
        test("is mandatory", async () => {
            const t = () => {
                const alloy = new Alloy({ ...defaultParams, name: undefined })
            };
            expect(t).toThrow(TypeError);
        })
    });
})

标签: javascripttypescript

解决方案


问题在于您的班级的定义。通过添加!s,您是在告诉 TS,您知道它不会是 undefined/null - 而不是它是必需的。

你永远不会遇到这样的运行时错误——因为所有类型检查都发生在编译时,而不是运行时。

如果您像这样声明类,那么您将允许 TS 向您展示问题:

export class Alloy {

    name: string

    constructor(data: Partial<Alloy>) {
        Object.assign<Alloy, Alloy>(this, {
            name: data.name,
        });
    }
}

现在您收到错误消息,告诉您 name 不能保证是未定义的,并且 data.name 也可能是未定义的,因此不能分配给必需的属性。


推荐阅读