нарушение машинописного текста - PullRequest
0 голосов
/ 28 июня 2018

Постановка задачи:

Определите переменную с типом number, но при назначении любой переменной в эту переменную и попробуйте transpile в JavaScript. Transpiler не дает никакой ошибки.

Демонстрация проблемы:

class.ts

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a, n, p) {
        this.age = a;
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44");

console.log(firstUser.getDetails());

В приведенном выше коде мы определили переменную age как number, но при создании экземпляра класса User я передаю age как "27", что является строкой. Следовательно, при переносе он должен выдавать ошибку, но он переносится в JavaScript без каких-либо ошибок.

Выход транспиляции:

enter image description here

Но в той же кодовой базе, если я непосредственно назначу строку переменной this.age в функции конструктора. Transpiler выдает ошибку.

class.ts

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a, n, p) {
        this.age = "27";
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44");

console.log(firstUser.getDetails());

Выход транспиляции:

enter image description here

1 Ответ

0 голосов
/ 28 июня 2018

Это ожидаемое поведение. Ваш конструктор имеет 3 параметра без аннотации типа, поэтому их неявный тип будет any. Вы можете назначить что-либо на any (чтобы вы могли назначить string на any), и вы можете назначить на any (чтобы вы могли назначить поле number из параметра a типа any). Обычно в этом случае any стирает тип того, что вы передали.

Поскольку a должно быть числом, мы должны предоставить явную аннотацию, и тогда мы получим ошибку, когда передадим string (и это ожидаемое поведение)

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a: number, n: string, p: number | string) {
        this.age = a;
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44"); // error
var secondUser = new User(27, "Rohit", "945*****44"); // ok

Вы можете избежать необходимости указывать тип дважды и выполнять присваивание, объявив поля как аргументы конструктора. Следующий код эквивалентен вышеуказанному классу:

class User {

    constructor(
        public age:number, // Both a constructor argument and a field declaration, the compiler will perform the this.age = age assignemet for us
        public name:string,
        public phone:number | string) {
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

Если вы хотите избежать неявного указания параметров и переменных типа any, вы можете использовать опцию компилятора noImplicitAny, чтобы получить ошибку, если аннотация типа не указана и тип не может быть выведен.

...