TypeScript Version: 2.7.0
Search Terms: interface, struct
Suggestion
It's confusing using interface to implement Types. As Typescript already allow us to use interface to ensure classes implements methods, and also check if the class had implemented that interface, it would be clearer if we could have a Struct for this purpose and leaving Interface for only restricting classes implementation.
Based on C# documentation I fond the following descriptions:
Struct:
A struct type is a value type that is typically used to encapsulate small groups of related variables, such as the coordinates of a rectangle or the characteristics of an item in an inventory.
Interface:
An interface contains only the signatures of methods, properties, events or indexers. A class or struct that implements the interface must implement the members of the interface that are specified in the interface definition.
Expected behavior:
struct CarModel {
name: string;
year: number;
}
const carModel: CarModel = {
name: 'VW',
year: 2018
}
Actual behavior:
interface CarModel {
name: string;
year: number;
}
const carModel: CarModel = {
name: 'VW',
year: 2018
}
it also allow to create interface to restrict classes implementation
interface Vehicle {
accelerate(): void;
currentSpeed(): number;
}
class Car implements Vehicle {
accelerate(): void {
//Vehicle forces implementing the method
}
currentSpeed(): number{
//Vehicle forces implementing the method
}
}
Reference:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/struct
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface
So we're not going to change this because this really is just a syntactic preference that is unlikely to change 5 years into the development of the language. That said, you've already described the main characteristic of structs:
A struct type is a value type
which is not true of object types that are created in TypeScript (barring whatever your JIT might do under the hood).
Meanwhile, looking at the cited description of interfaces:
Interface:
An interface contains only the signatures of methods, properties, events or indexers.
we see that's basically what interfaces in TypeScript do right now.
it also allow to create interface to restrict classes implementation
TypeScript allows you to do this with interfaces today as well.
The fact that interfaces serve both purposes of plain object types as well as contracts is an intentional feature of TypeScript. They are meant to describe the structural nature of objects in JavaScript.
Hi @DanielRosenwasser,
We can have both Interface implementations below:
Using it as a DataType / Struct
interface MyData {
prop1: string;
prop2: number
}
const myData: MyData = <MyData>{
prop1: 'Property One',
prop2: 1
}
Using it as a class Interface
interface Vehicle {
accelerate(): void;
currentSpeed(): number;
}
class Car implements Vehicle {
name: string;
model: string;
accelerate(): void {
//implementation forced by Vehicle Interface
}
currentSpeed(): number {
//implementation forced by Vehicle Interface
}
}
class Truck implements Vehicle {
name: string;
model: string;
accelerate(): void {
//implementation forced by Vehicle Interface
}
currentSpeed(): number {
//implementation forced by Vehicle Interface
}
}
const car = new Car();
if (car implements Vehicle) {
//check if the class implements the interface
}
//Or alsoe
const car = new Car();
const truck = new Truck();
goFaster(vehicle: Vehicle): void {
vehicle.accelerate();
}
//Both works as they implements Vehicle Interface
this.goFaster(car);
this.goFaster(truck);
//A generic method to have any parameter
getCurrentSpeed(anyVehicle: any) {
//Check implementation of Vehicle to access the "currentSpeed" method
if (anyVehicle implements Vehicle) {
return anyVehicle.currentSpeed();
}
}
I'm writing above just a simple example for both scenarios we can implement interfaces using TypeScript.
That's the point what I meant on the post, implementing Interface as a Data Struct which you can set a variable, or having an Interface as an implementation for a class just make it feels confusing.
Their purpose are completely different, what do you reckon?
The fact that interfaces serve both purposes of plain object types as well as contracts is an intentional feature of TypeScript.
So why having a same syntax to implement 2 different things? It would be clearer to have something like "Struct" for only contracts, and "Interface" for an OOP purpose. Wouldn't be clearer?
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Most helpful comment
So we're not going to change this because this really is just a syntactic preference that is unlikely to change 5 years into the development of the language. That said, you've already described the main characteristic of structs:
which is not true of object types that are created in TypeScript (barring whatever your JIT might do under the hood).
Meanwhile, looking at the cited description of interfaces:
we see that's basically what interfaces in TypeScript do right now.
TypeScript allows you to do this with interfaces today as well.
The fact that interfaces serve both purposes of plain object types as well as contracts is an intentional feature of TypeScript. They are meant to describe the structural nature of objects in JavaScript.