如何在 TypeScript 中正确更改变量的类型?

问题描述 投票:0回答:6

感谢您的耐心等待,我刚刚开始使用 TypeScript。

我正在开发一个 Angular 2 应用程序,它需要接受文本输入,然后进行大量计算。我(错误地?)假设我需要首先将输入绑定到数据模型中的“任何”类型变量,然后将这些变量转换为数字以便处理数字。我环顾四周,找不到如何以不抛出此 TS 编译器错误的方式执行此操作:

`src/calculator_service.ts(40,5): error TS2322: Type 'number' is not assignable to type 'string'.`

在我的 CalculatorService 中,我有这个功能:

/*
 * Convert the object of strings recieved from the form into a clean object of integers
 */
n(model:ModelFields) {
    // Clone it
    this.numericModel = Object.assign({}, this.model);

    for (var prop in this.numericModel) {
        if (this.numericModel.hasOwnProperty(prop)) {

            // strip off all non-numeric charactersklj
            this.numericModel[prop] = this.numericModel[prop].replace(/\D/g,'');

            // convert to Any typescript type
            // this breaks the application, and still throws a compiler error. nope.
            // this.numericModel[prop] = this.numericModel[prop]:Any;

            // convert to Number type
            // this gives a typescript console error, but seems to still compile... 
            // ignoring this for now in order to meet deadline
            this.numericModel[prop] = +this.numericModel[prop];

        }
    }

    return this.numericModel;
}

以及 ModelFields 定义(感谢 tarh!)

export class ModelFields { 
    constructor( 
        public fieldName: any, 
        public anotherField: any 
    ) 
    {} 
}

有什么想法吗?谢谢大家!

typescript angular typescript1.5
6个回答
39
投票

您无法在 TypeScript 中更改变量的类型,这与 TS 的用途相反。相反,您可以将变量声明为“any”,这相当于 JS 中经典的“var”变量,无类型。

一旦声明变量,您将无法重新输入它。然而,您可以做的是声明“any”,然后在您想要使用它时强制转换它,以便将其用作所需的类型。

例如,这不会引发任何错误:

let a: any;

a = 1234;
(a as number).toExponential();

a = "abcd"; 
(a as string).substr(1, 4);

对于您的课程,这也是正确的,没有类型错误:

class ModelFields { 
    constructor( 
        public fieldName: any, 
        public anotherField: any 
    ) 

    //...
}

let model: ModelFields = new ModelFields(1, 2);

console.log(model.fieldName + model.anotherField);    // --> 3

model.fieldName = "a";
model.anotherField = "b";

console.log(model.fieldName + model.anotherField);    // --> ab

4
投票

你的例子不够清楚,但我猜你的问题是因为Typescript inference

var x = 3; // x is a number
x = "45";  // compiler error

但是,如果你这样做:

var x : any = 3; // x can be anything
x = "45";

或者:

var x; // x is any forever
x = '45';  // x is still any

您可以在那些很棒的幻灯片文档

上找到更多详细信息

希望这能有所帮助...


2
投票

您可以通过省略旧类型中的属性然后将它们添加回来来创建新类型。

这不会起作用。

interface DbItem { _id: Buffer date: number } interface JsItem extends DbItem { _id: string }
但是您可以使用实用程序类型

Omit

省略要更改的类型,然后将它们添加回来。

interface DbItem { _id: Buffer date: number } interface JsItem extends Omit<DbItem, '_id'> { _id: string }
    

0
投票
面临类似类型的查询并为我工作。

我的案例:

article Id

 来自路由参数的字符串格式,我从 API 获取数字格式的数据。

如果我用 != 检查,ES lint 会抛出错误。所以我使用 Number() 方法将字符串转换为普通 javascript 中的数字。

const articleId = Number(this.route.snapshot.params['articleId']); data.forEach((element, index) => { // console.log(typeof(element['id']), element['id']); // 4, number // console.log(typeof(this.route.snapshot.params['articleId']), this.route.snapshot.params['articleId']); // 4, string (converted to number) if (element['id'] !== articleId) { //my implementation } }

参考链接:

  1. https://gomakethings.com/converting-strings-to-numbers-with-vanilla-javascript/

0
投票
重新声明变量:

// Re-declare the variable let value: any = Date.now() % 2 === 0 ? "string" : 124875; if (typeof value === 'string') { let str: string = value as string; } else { let num: number = value as number; }
或映射到另一个类实例:

export class ModelField { constructor(public fieldName: any) {} } export class StringField { public x: string; constructor(model: ModelField) { this.x = model.fieldName as string; } } let value: any = Date.now() % 2 === 0 ? "string" : 124875; let model: ModelField = new ModelField(value); if (typeof model.fieldName === 'string') { let strField: StringField = new StringField(model); } else { let numField: NumberField = new NumberField(model); }
    

0
投票
最简单的方法是

let b = (a 作为对象) 作为类型; // 这里的类型可以是任何数据类型

© www.soinside.com 2019 - 2024. All rights reserved.