简体   繁体   中英

Using interfaces in TypeScript when I am waiting to see a class declaration

We have faced with a confused case of using interface declaration is used in TypeScript. for example: What is a reason to use interface for models?

I opened TypeScript tutorial

and see the example of using interface and class together.

And there are Person interface is min set of data, which our greeter function from Student class to execute your functionality.

From example :

class Student {
  fullname : string;
  constructor(public firstname, public middleinitial, public lastname) {
    this.fullname = firstname + " " + middleinitial + " " + lastname;
  }
}

interface Person {
  firstname: string;
  lastname: string;
}

function greeter(person : Person) {
   return "Hello, " + person.firstname + " " + person.lastname;
}

var user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

And generated javascript code does not know any Person structure data from example :

var Student = (function () {
function Student(firstname, middleinitial, lastname) {
    this.firstname = firstname;
    this.middleinitial = middleinitial;
    this.lastname = lastname;
    this.fullname = firstname + " " + middleinitial + " " + lastname;
}
return Student;
})();
function greeter(person) {
  return "Hello, " + person.firstname + " " + person.lastname;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);

I have started to use the same syntax. And My interfaces were without 'I' prefix in their name.

But my application contains interfaces like in C# where they are contract. Such interface I want to name using 'I' prefix. And it is confused to me have 'virtual' data structure like Person, which declared using interface keyword and contracts in my application without 'I'.

For example, I wrote the following code:

interface IStudentActivity {

   attentCurse();

}

class Person {
   firstname: string;
   lastname: string;
   middleinitial: string;
}

class Student extends Person, IStudentActivity {
  fullname : string;
  constructor(firstname, middleinitial, lastname) {

    super();

    this.firstname=firstname;
    this.middleinitial=middleinitial;
    this.lastname=lastname;


    this.fullname = this.firstname + " " + 
    this.middleinitial + " " + this.lastname;
  }

  attentCurse(): void {
    alert("math");
  }
}

function addPerson(firstName: string, lastName: string): Person {

  var person = new Person();
  person.firstname = firstName;
  person.lastname = lastName; 

  return person;
} 


function greeter(person : Person) {
  return "Hello, " + person.firstname + " " + person.lastname;
}

var user = new Student("Jane", "M.", "User");
user.attentCurse();

document.body.innerHTML = greeter(user);

var newGuy = addPerson("Bob", "White");

alert(greeter(newGuy));

In this case, TypeScript shows me an error in a place where Student extends Person, IStudentActivity that ' Classes can only extend a single class '. It would be nice to have the feature in TypeScript like in C#.

When we declared Person as class, then tsc generates Person data structure:

var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype,        new __());
};
var Person = (function () {
    function Person() {
   }
   return Person;
 })();
 var Student = (function (_super) {
   __extends(Student, _super);
   function Student(firstname, middleinitial, lastname) {
    _super.call(this);
    this.firstname = firstname;
    this.middleinitial = middleinitial;
    this.lastname = lastname;
    this.fullname = this.firstname + " " +
        this.middleinitial + " " + this.lastname;
  }
  Student.prototype.attentCurse = function () {
      alert("math");
  };
  return Student;
})(Person);
function addPerson(firstName, lastName) {
var person = new Person();
person.firstname = firstName;
person.lastname = lastName;
return person;
}
function greeter(person) {
 return "Hello, " + person.firstname + " " + person.lastname;
}
var user = new Student("Jane", "M.", "User");
user.attentCurse();
document.body.innerHTML = greeter(user);
var newGuy = addPerson("Bob", "White");
alert(greeter(newGuy));

I have come from C#, and now this is a little bit confused to see how interface keyword is used in TypeScript.

Is it make sense to use classes for such data structure like Person, and interface is for contracts?

I have worked as a team and each guy has different experience with OOP, but for all it is a confused to see Person data structure as interface.

What is a reason to use interface for models? I see that javascript does not contain this structure, but for example our application is growing and we in our team spending more time to understand where is a contract and where is a model.

In Typescript interfaces are only there for the compiler. They will not be emitted in the final javascript code. However the implementations will be checked, if the interface is implemented properly in classes.

This line: class Student extends Person, IStudentActivity does not work because you can't extend from multiple classes as the error says. Typescript does not support multiple inheritance.

If you want to implement Student which should meet the interface IStudentActivity requirements and extend the Person class you should write:

class Student extends Person implements IStudentActivity

Hope that helps.

Use interfaces for models (data transfer objects), or method contracts, and classes for logic. Reason is that interfaces will give you compiler errors when you miss a property, and classes will not. Take an example:

interface IPerson{
    Name: string;
    Age: number;    
}

class Person{
    Name:string;
    Age: number;
}

var p1: IPerson = {
    Age: 23 //this will give error because Name is missing
}

var p2 = new Person(); //this will initialize a class without any actual properties
console.log(p1.Name.length); // normally this will cause error because p1.Name is not initialized
console.log(p2.Name.length);//similarly, but the compiler won't notice the class

In javascript, a "class" is just a function with a name that gives you an object, meaning when you define a class Person there will actually be a variable named "Person". An interface in Typescript is just an empty shell, containing nothing but constraints.

If you want to have a contract in both Data and Methods, consider using abstract classes (supported with TS1.6)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM