Как определить статическое свойство в интерфейсе TypeScript



Я просто хочу объявить статическое свойство в typescript интерфейс? Я ничего не нашел по этому поводу.



interface myInterface {
static Name:string;
}


это возможно?

811   8  

8 ответов:

вы не можете определить статическое свойство на интерфейсе в TypeScript.

скажем, вы хотели изменить

следуйте ответу @Duncan @ Bartvds, здесь, чтобы обеспечить работоспособный способ после нескольких лет.

на данный момент после выпуска Typescript 1.5 (@Jun 15 '15), ваш полезный интерфейс

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

может быть реализован таким образом, с помощью декоратора.

/* class decorator */
function staticImplements<T>() {
    return (constructor: T) => {}
}

@staticImplements<MyTypeStatic>()   /* this statement implements both normal interface & static interface */
class MyTypeClass { /* implements MyType { */ /* so this become optional not required */
    public static staticMethod() {}
    instanceMethod() {}
}

см. мой комментарий на github открыть выпуск 13462.

визуальный результат: Ошибка компиляции с подсказкой статического метода недостающий. enter image description here

после реализации статического метода, подсказка для метода отсутствует. enter image description here

компиляция прошла после выполнения как статического интерфейса, так и обычного интерфейса. enter image description here

статические свойства обычно размещаются в (глобальном) конструкторе для объекта, тогда как ключевое слово "interface" применяется к экземплярам объекта.

предыдущий ответ, Конечно, правильный, если вы пишете класс в TypeScript. Это может помочь другим узнать, что если вы описываете объект, который уже реализован в другом месте, то глобальный конструктор, включая статические свойства, может быть объявлен следующим образом:

declare var myInterface : {
  new(): Interface;
  Name:string;
}

вы можете определить интерфейс нормально:

interface MyInterface {
    Name:string;
}

но вы не можете просто сделать

class MyClass implements MyInterface {
    static Name:string; // typescript won't care about this field
    Name:string;         // and demand this one instead
}

чтобы выразить, что класс должен следовать этому интерфейсу для его статических свойств, вам нужно немного хитрости:

var MyClass: MyInterface;
MyClass = class {
    static Name:string; // if the class doesn't have that field it won't compile
}

вы даже можете сохранить имя класса, TypeScript (2.0) не будет возражать:

var MyClass: MyInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that field it won't compile
}

если вы не хотите наследовать от многих интерфейсов статически, вам придется сначала объединить их в новый один:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
interface NameAndAddressInterface extends NameInterface, AddressInterface { }
var MyClass: NameAndAddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

или если вы не хотите называть объединенный интерфейс, вы можете сделать:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
var MyClass: NameInterface & AddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

работающего пример

решение@duncan выше указания new() для статического типа работает также с интерфейсами:

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

Если вы хотите определить статический класс (т. е. все методы/свойства статичны), вы можете сделать что-то вроде этого:

interface MyStaticClassInterface {
  foo():string;
}

var myStaticClass:MyStaticClassInterface = {
  foo() {
    return 'bar';
  }
};

в этом случае статический "класс" на самом деле просто простой-ol'-js-объект, который реализует все методы MyStaticClassInterface

Я нашел способ сделать это (без отделочников) для моего конкретного случая использования.

важная часть, которая проверяет статические члены IObjectClass и с помощью cls: IObjectClass<T> на createObject способ:

//------------------------
// Library
//------------------------
interface IObject {
  id: number;
}
interface IObjectClass<T> {
  new(): T;
  table_name: string;
}
function createObject<T extends IObject>(cls: IObjectClass<T>, data:Partial<T>):T {
  let obj:T = (<any>Object).assign({},
    data,
    {
      id: 1,
      table_name: cls.table_name,
    }
  )
  return obj;
}

//------------------------
// Implementation
//------------------------
export class User implements IObject {
  static table_name: string = 'user';
  id: number;
  name: string;
}

//------------------------
// Application
//------------------------
let user = createObject(User, {name: 'Jimmy'});
console.log(user.name);

Вы можете объединить интерфейс с пространством имен используя то же имя:

interface myInterface { }

namespace myInterface {
  Name:string;
}

но этот интерфейс полезен только для того, чтобы знать, что у него есть свойство Name. Вы не можете его реализовать.

Comments

    Ничего не найдено.