What is the difference between type and class in Typescript?

Multi tool use
What is the difference between type and class in Typescript?
What is the difference between type
and class
?
type
class
type Point {
x: number, y: number
}
let p = new Point();
The above results in:
'Point' only refers to a type, but is being used as a value here.
Why is this so? I am not certainly not using Point
as a value but using it to instantiate a type.
Point
What are the situations where I would need to use type
because class
is not suitable?
type
class
How do I instantiate a type?
– Old Geezer
Jul 2 at 8:37
@OldGeezer: read the comment again. It's just a type hint to the compiler. Is transformed to absolutely nothing in javascript. You can't instantiate nothing.
– Sergio Tulentsev
Jul 2 at 8:45
let p: Point = { x: 10, y: 15 };
in Sefe's and Titian's answers was what I was asking.– Old Geezer
Jul 2 at 8:58
let p: Point = { x: 10, y: 15 };
3 Answers
3
Typescript has two different universes that come into contact in some points: Value space and Type space. Type space is where types are defined and types get erased completely and don't exist at runtime. Value space contains values and will obviously exist at runtime.
What is a value? Value literals, variables, constants and parameters are obviously values. Functions and classes are also values as they do have a runtime object backing them up, namely the function object and the class constructor (also a function). Enums are also values as they are backed up by an object at runtime.
What is a type? Any definition with a type
keyword is a type as well as interfaces, classes and enums
type
You will notice I mentioned classes in both spaces. Classes exist in both type space, and value space. This is why we can use them both in type annotations (let foo: ClassName
) and in expressions (ex new ClassName()
).
let foo: ClassName
new ClassName()
Enums also span both worlds, they also represent a type we can use in an annotation, but also the runtime object that will hold the enum.
Names in type space and value space don't collide, this is why we can define both a type and a variable with the same name:
type Foo = { type: true }
var Foo = { value : true } // No error, no relation to Foo just have the same name in value space
Classes and enums, since they span both spaces will 'use up' the name in both spaces and thus we can't define a variable or a type with the same name as a class or enum (although we can do merging but that is a different concept)
In your specific case, Point
is just a type, something we can use in type annotations, not something we can use in expressions that will need to have a runtime presence. In this case the type is useful as it allows the compiler to structurally check that the object literal is assignable to the Point
type:
Point
Point
let p: Point = { x: 10, y: 15 }; // OK
let p: Point = { x: 10, y: 15, z: 10 }; // Error
If you want to create a class, you will need to do that with the class
keyword, as that will create a runtime value that is not just a type:
class
class Point{
constructor(public x: number, public y: number){}
}
let p = new Point(10,10)
You use a type
(or in other cases an interface
) for type annotations to indicate the structure of JavaScript objects:
type
interface
type Point = {
x: number, y: number
}
function doSomething(p: Point) {
}
let p: Point = { x: 10, y: 15 };
doSomething(p);
These type annotations are subject to structural typing, meaning that in this specific case you could drop the type annotation:
let p = { x: number, y: number };
doSomething(p);
A class is something entirely different, which provides you a more elegant alternative to JS prototype inheritance:
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);
When you look at the generated JS code, you will quickly notice the difference:
The type
declaration is dropped in the generated code.
type
The class definition is turned into a JS function with prototype inheritance
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
You can use new only with classnames. But Point is not a classname, but a value.
class Point{
private x;
private y;
constructor(x,y) {
this.x = v1;
this.y = v2;
}
}
Now Point is a class and you can do:
let p = new Point(1,2);
But Point is not a classname, but a value
, no that's the point. It is defined in type space only; the single most important point here is that a type is not a value.– Duncan
Jul 2 at 9:15
But Point is not a classname, but a value
In runtime thats true. But in runtime its Javascript not Typescript.
– Nils Fett
Jul 2 at 9:46
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
A TypeScript/JavaScript class is a function. A TypeScript type is just a definition that helps the TS compiler check the code. It is not translated to anything in the generated JS code.
– axiac
Jul 2 at 8:35