简体   繁体   English

等待看到类声明时在TypeScript中使用接口

[英]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. 我们面临一个在TypeScript中使用接口声明的混乱情况。 for example: What is a reason to use interface for models? 例如:为模型使用界面的原因是什么?

I opened TypeScript tutorial 我打开了TypeScript教程

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. 而且Person界面是最小的数据集,我们的Student类的greeter函数可以用来执行您的功能。

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 : 并且生成的javascript代码不包含来自示例的任何Person结构数据:

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. 我的界面名称中没有前缀“ I”。

But my application contains interfaces like in C# where they are contract. 但是我的应用程序包含像C#这样的接口,它们是契约的。 Such interface I want to name using 'I' prefix. 我想使用“ I”前缀来命名此类接口。 And it is confused to me have 'virtual' data structure like Person, which declared using interface keyword and contracts in my application without 'I'. 而且让我感到困惑的是像“人”这样的“虚拟”数据结构,它使用接口关键字声明并且在我的应用程序中没有“ 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 '. 在这种情况下,TypeScript在学生扩展Person,IStudentActivity的地方向我显示了一个错误,即“ 类只能扩展单个类 ”。 It would be nice to have the feature in TypeScript like in C#. 像C#中那样在TypeScript中具有该功能将是很好的。

When we declared Person as class, then tsc generates Person data structure: 当我们将Person声明为类时,则tsc生成Person数据结构:

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. 我来自C#,现在对在TypeScript中如何使用interface关键字感到有些困惑。

Is it make sense to use classes for such data structure like Person, and interface is for contracts? 为类(例如Person)这样的数据结构使用类,并且接口用于合同,是否有意义?

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. 我曾作为一个团队工作过,每个人在OOP方面都有不同的经验,但总的来说,将Person数据结构视为接口很困惑。

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. 我看到javascript不包含此结构,但是例如我们的应用程序正在增长,我们团队中的人们花费更多的时间来了解合同在哪里以及模型在哪里。

In Typescript interfaces are only there for the compiler. 在Typescript中,接口仅用于编译器。 They will not be emitted in the final javascript code. 它们不会在最终的javascript代码中发出。 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. 这行代码: class Student extends Person, IStudentActivity不起作用,因为您不能按照错误说明从多个类扩展。 Typescript does not support multiple inheritance. Typescript不支持多重继承。

If you want to implement Student which should meet the interface IStudentActivity requirements and extend the Person class you should write: 如果要实现满足接口IStudentActivity要求的Student并扩展Person类,则应编写:

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". 在javascript中,“类”只是一个具有给您对象的名称的函数,这意味着当您定义类Person时,实际上将有一个名为“ Person”的变量。 An interface in Typescript is just an empty shell, containing nothing but constraints. Typescript中的接口只是一个空的外壳,除了约束之外什么都没有。

If you want to have a contract in both Data and Methods, consider using abstract classes (supported with TS1.6) 如果要在数据和方法中都具有合同,请考虑使用抽象类(受TS1.6支持)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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