【问题标题】:TypeScript: Casting result to custom type not workingTypeScript:将结果转换为自定义类型不起作用
【发布时间】:2020-01-19 13:33:15
【问题描述】:

我的 Person 类型定义如下

import moment from "moment";

export default class Person {
    constructor() {
        this.id = -1;
        this.name = "";
        this.dob = new Date();
        this.gender = "M";
        this.photo = "";
        this.salary = 0.0;
    }

   public id: number;
   public name: string;
   public dob: Date;
   public get dobString(): string{
        return moment(this.dob).toString();
   };
   public gender: string;
   public photo: string;
   public salary: number;
}

在上面的 Person 类型中,您可以看到我有一个只读属性 dobString(),它几乎以字符串格式返回日期。

现在我有一个返回记录集合的 get 方法。我将集合投射到<Person[]>,但结果不包括属性dobString()。您能否在我的代码下方验证并告诉我我缺少什么?

getAll (req: Request, res: Response, next: NextFunction) {
    var pageNumber = req.query.pageNumber;
    var pageSize = req.query.pageSize;

    db.query("CALL person_selectall(?, ?, @total); SELECT @total as TotalRecords;", [pageNumber, pageSize], (err: Error, rows: any[], fields: any) => {
        let result = new PageResult<Person>(pageSize, pageNumber, 0);

        if (!err) {
            result.IsSuccessful = true;
            result.TotalRecords = rows[2][0].TotalRecords;
            result.Data = <Person[]> rows[0];//result.Data is of type Person[]
            res.send(result);
        } else {
            result.IsSuccessful = false;
            result.TotalRecords = 0;
            result.ReasonForFailure = JSON.stringify(err);
            result.Data = [];
            res.send(result);
        }
    });
}

更新(2019 年 9 月 20 日)

目前,我已经使用 Map 方法实现了(见下文)。如果有更好的方法,请告诉我。

const personArray = rows[0].map((row: any) => {
                const person = new Person();
                person.Id = row.id;
                person.Name = row.name;
                person.Gender = row.gender;
                person.Dob = row.dob;
                person.DobString = moment(person.Dob).format(config.get("format.date"));
                person.Photo = row.photo;
                person.Salary = row.salary;
                person.CreatedDate = row.createddate;
                person.CreatedDateString = moment(person.CreatedDate).format(config.get("format.datetime"));
                person.ModifiedDate = row.modifieddate;
                person.ModifiedDateString = person.ModifiedDate === null ? null : moment(person.ModifiedDate).format(config.get("format.datetime"));
                return person;
            });
            result.Data = personArray;

谢谢, 赫曼特。

【问题讨论】:

    标签: typescript casting


    【解决方案1】:

    result.Data = &lt;Person[]&gt; rows[0];

    请记住,当 typescript 被转译时,所有类型注释都会消失,而您只剩下显示 result.Data = rows[0] 的 javascript。该代码不会向该对象添加任何不存在的属性。

    使用像&lt;Person[]&gt; 这样的类型断言的目的不是对数据进行任何更改。目的是告诉打字稿“我比你更了解,所以不要在这里检查我的类型”。如果你真的比打字稿更了解,那没关系。但是如果你断言对象有一个 dobString 函数,而实际上它没有,typescript 只会信任你,并且无法指出错误。

    【讨论】:

    • 那么有没有办法让我的结果包括我的自定义类型的所有成员?如果是这样,你能分享一下sn-p来实现这个吗?
    • 好吧,如果这只是 javascript,你想做什么?可能调用new Person 一次或多次,从rows 传入数据。我不确定你到底想要什么代码,因为我不知道行的结构,而且你的 Person 构造函数看起来不像它设置为传递属性。
    • 看起来我将不得不在循环中将数据从行映射到我的自定义类型集合。让我知道是否有更好的方法
    • 我已经用临时解决方案更新了我的请求。
    猜你喜欢
    • 1970-01-01
    • 2012-09-10
    • 2016-11-24
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    相关资源
    最近更新 更多