web-dev-qa-db-ja.com

TypeScriptで変数の型を適切に変更するにはどうすればよいですか?

ここであなたの忍耐をありがとう、私はTypeScriptから始めています。

私はangular 2のアプリで、テキスト入力を受け入れ、一連の計算を行う必要があります。私は(誤って?)最初に入力を "any"にバインドする必要があると想定していましたデータモデル内に変数を入力し、それらの変数を数値に変換して数値を計算します。私はすべてを調べましたが、この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 
    ) 
    {} 
}

何か案は?みんなありがとう!

13
ryanrain

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
10
josemigallas

あなたの例は十分に明確ではありませんが、あなたの問題はTypeScript推論が原因であると思います:

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

これらの素晴らしいスライドdocs で詳細を確認できます

これが少し役立つことを願っています...

1
Yaniv Efraim

同様のタイプのクエリに直面し、私のために働いた。

私の場合:

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