【问题标题】:Checking the structure of an object returned by a http service against a typescript interface根据 typescript 接口检查 http 服务返回的对象的结构
【发布时间】:2018-02-03 13:31:47
【问题描述】:

我想检查 http JSON 响应的内容/结构确实与打字稿接口/类型匹配。这是在针对正在运行的后端进行 javascript 集成测试的上下文中。

例如,我们的 typescript 接口之一如下:

export interface CurrentUser {
  id: number;
  firstname: string;
  lastname: string;
  roles: string[];
}

如果后端返回一个包含age 属性但没有firstname 属性的对象,那么我希望在运行时以某种方式通知返回对象的结构不同并且测试将失败。

另外,我想避免为每个字段手动编写检查/断言代码。

我了解 typescript 接口在运行时不再存在。那我怎么能依赖打字稿来做这样的检查呢?

如果打字稿无法做到这一点,那么有什么替代方案(库、模式)?

【问题讨论】:

标签: javascript typescript


【解决方案1】:

没有本机方法可以直接使用 typescript 接口来执行运行时类型断言。您应该创建自己的 javascript 实现。

(i) 有一个unofficial TS compiler 允许自动执行此过程。

另外,我想避免为每个字段手动编写检查/断言代码。

不幸的是,除非您决定使用诸如自定义编译器之类的解决方案,否则您将不得不这样做。例如,您可以像这样测试对象:

const isValidUser = (object) => {
    if ('object' !== typeof object) return false;

    const { id, firstname, lastname, roles } = object;
    
    return typeof id === 'number'
        && typeof firstname === 'string'
        && typeof lastname === 'string'
        && Array.isArray(roles)
        && roles.reduce((acc, value) => acc && typeof value === 'string', true);
}

// prints false (missing lastname property)
document.body.innerText = isValidUser({
    id: 1,
    firstname: 'John',
    roles: ['admin', 'content-editor'],
});

上面的示例对所有属性(存在和类型)执行所有基本检查。此外,您可以使用 LodashRamda 之类的库来清理类型检查语法,并使事情更容易理解(和维护)。一个例子:

const { all, allPass, pipe, prop } = R;
const { isArray, isNumber, isObject, isString } = _;

const isValidUser = allPass([
    isObject,
    pipe(prop('id'), isNumber),
    pipe(prop('firstname'), isString),
    pipe(prop('lastname'), isString),
    pipe(prop('roles'), isArray),
    pipe(prop('roles'), all(isString)),
]);

// prints false (missing lastname property)
document.body.innerText = isValidUser({
    id: 1,
    firstname: 'John',
    roles: ['admin', 'content-editor'],
});
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

【讨论】:

    猜你喜欢
    • 2020-10-30
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    相关资源
    最近更新 更多