В чем разница между типом и классом в Typescript? - PullRequest
0 голосов
/ 02 июля 2018

В чем разница между type и class?

type Point {
  x: number, y: number
}

let p = new Point();

Результат выше:

«Точка» относится только к типу, но здесь используется в качестве значения.

Почему это так? Я определенно не использую Point в качестве значения, но использую его для создания экземпляра типа.

В каких ситуациях мне нужно было бы использовать type, потому что class не подходит?

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Вы используете type (или в других случаях interface) для аннотаций типов, чтобы указать структуру объектов JavaScript:

type Point = {
  x: number, y: number
}

function doSomething(p: Point) {
}

let p: Point = { x: 10, y: 15 };
doSomething(p);

Эти аннотации типов подлежат структурной типизации, что означает, что в данном конкретном случае вы можете удалить аннотацию типа:

let p = { x: number, y: number };
doSomething(p);

Класс - это нечто совершенно иное, что предоставляет вам более элегантную альтернативу наследования прототипов JS:

class Point {
    public x: number;
    public y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    public move(deltaX: number, deltaY: number) {
        this.x = this.x + deltaX;
        this.y = this.y + deltaY;
    }
}

let p = new Point(10, 15);
p.move(1, 2);

Когда вы посмотрите на сгенерированный код JS, вы быстро заметите разницу:

Объявление type отброшено в сгенерированном коде.

Определение класса превращается в функцию JS с наследованием прототипа

0 голосов
/ 02 июля 2018

Typescript имеет две разные вселенные, которые соприкасаются в некоторых точках: пространство значений и пространство типов. Пространство типов - это место, где типы определены, а типы полностью стираются и не существуют во время выполнения. Пространство значений содержит значения и, очевидно, будет существовать во время выполнения.

Что такое стоимость? Значения литералов, переменных, констант и параметров, очевидно, являются значениями. Функции и объявления классов также являются значениями, так как они имеют объект времени выполнения, поддерживающий их, а именно объект функции и конструктор класса (также функция). Перечисления также являются значениями, поскольку они резервируются объектом во время выполнения.

Что такое тип? Любое определение с ключевым словом type является типом, а также интерфейсами, объявлениями класса и перечисления

Вы заметите, что я упомянул объявления классов в обоих местах. Классы существуют как в пространстве типов, так и в пространстве значений. Вот почему мы можем использовать их как в аннотациях типов (let foo: ClassName), так и в выражениях (например, new ClassName()).

Перечисления также охватывают оба мира, они также представляют тип, который мы можем использовать в аннотации, но также и объект времени выполнения, который будет содержать перечисление.

Имена в пространстве типов и в пространстве значений не сталкиваются, поэтому мы можем определить и тип, и переменную с одинаковыми именами:

type Foo = { type: true }
var Foo = { value : true } // No error, no relation to Foo just have the same name in value space 

Объявления и перечисления классов, поскольку они охватывают оба пробела, будут «использовать» имя в обоих пробелах, и поэтому мы не можем определить переменную или тип с тем же именем, что и у объявления или перечисления класса (хотя мы можем сделать слияние, но это другая концепция)

В вашем конкретном случае Point - это просто тип, который мы можем использовать в аннотациях типов, а не то, что мы можем использовать в выражениях, которые должны присутствовать во время выполнения. В этом случае тип полезен, так как он позволяет компилятору структурно проверить, что литерал объекта может быть присвоен типу Point:

let p: Point = { x: 10, y: 15 }; // OK
let p: Point = { x: 10, y: 15, z: 10 }; // Error

Если вы хотите создать класс, вам нужно сделать это с ключевым словом class, так как это создаст значение времени выполнения, а не просто тип:

class Point{
    constructor(public x: number, public y: number){}
}
let p = new Point(10,10)
0 голосов
/ 02 июля 2018
class myClass extends myParentClass implements myInterface{

}

let value = new myClass();

// value is from type any and from type myClass and from type myParentClass and from type myInterface. Its class is myClass

Вы можете использовать новый только с именами классов. Но Point - это не имя класса, а значение.

class Point{
    private x;
    private y;
    constructor(x,y) {
        this.x = v1;
        this.y = v2;
    }
}

Теперь Point - это класс, и вы можете сделать:

let p = new Point(1,2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...