【问题标题】:TypeScript: 'number | undefined' is not assignable to parameter of type 'number'打字稿:'数字| undefined' 不可分配给“number”类型的参数
【发布时间】:2020-06-06 18:29:59
【问题描述】:

我有一个带有 Activiy 接口和 Mongo Schema 的模型,以及一个接受 ID 并记录它的函数。 然后在我的路线中,我查询来自未定义 externalId 的给定客户的所有活动。使用返回的数组,我调用模型中定义的函数,将 externalId 作为参数传递。

但是 TypeScript 一直在抛出:'number | 类型的参数undefined' 不能分配给“number”类型的参数。类型“未定义”不可分配给类型“数字”。 我已经尝试使用 if 语句检查是否为 externalId && typeof externalId === 'number' 来包装调用,但我无法让错误消失。

型号:

import { Schema, model, } from 'mongoose';

interface IActivity {
    customer: string,
    externalId?: number,
}

const activitySchema: Schema = new Schema({
    Customer: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 50,
    },
    externalId: { type: Number, },
});

export function updateExternal(externalId: number): void {
    console.log(externalId);
}

export const Activity = model<IActivityModel>('Activity', activitySchema);

路线:

const completeActivity = await Activity
    .find({
        'externalId': { '$ne': undefined, },
        'customer': 'Foo Customer',
    });

completeActivity.forEach((activity) => {
     updateExternal(activity.externalId); // This is where the error appears
});

【问题讨论】:

  • 如果activity 没有extenralId 会怎样?您需要设置默认值还是根本不调用updateExternal

标签: node.js typescript


【解决方案1】:

当键可能真的没有值时,思考应该发生什么以获取键的值是很有趣的。 activity.externalId 的类型为 number | undefined,那么我们要怎么做才能从 number | undefined 移动到 number

我们需要“移除”该类型的那一部分,也就是说,我们需要提供某种方法将number | undefined 的所有undefined 部分转换为number

我们通常通过提供一些默认值来做到这一点——我们说只要值是undefined,就不要使用它——改用默认值。但是,使用 typescript 很难找到一个好的类型;我们无法指定对象的类型具有我们正在寻找的属性;所以我们必须简单地说它可以是any,因此该函数只能返回any,如:

interface IX {
    a?: number;
}

function propOr<K extends string | number, U, O extends Record<K, U>>(k: K, defaultValue: U, obj: O) {
    return obj[k];
}

const testFunction1 = (x: IX) => x.a;                // has type number | undefined
const testFunction2 = (x: IX) => propOr('a', -1, x); // type error: 

我们在这里得到的类型错误是:

'IX' 类型的参数不能分配给'Record' 类型的参数。 属性“a”的类型不兼容。 输入'号码 | undefined' 不可分配给类型 'number'。 类型“未定义”不可分配给类型“数字”。(2345)

我们可能会查看其他库,看看它们是做什么的,例如,Sanctuary 有:

prop(p: string): (q: any) => any;

所以当我们输入一个函数时,我们有点卡住了,我们不得不丢失类型信息(除非其他人有更好的想法)。

我能想到的最佳解决方案是只使用 or 总是得到一个数字:

interface IX {
    a?: number;
}

const a: IX = {};
const b = a.a || 0;

现在b 的类型为number

【讨论】:

    猜你喜欢
    • 2017-04-23
    • 2023-01-16
    • 2023-02-22
    • 1970-01-01
    • 2019-04-10
    • 2023-01-11
    • 2018-09-29
    • 1970-01-01
    • 2016-09-26
    相关资源
    最近更新 更多