Я просто хочу объявить статическое свойство в интерфейсе typescript? Я ничего не нашел по этому поводу.
interface myInterface {
static Name:string;
}
Возможно ли это?
Я просто хочу объявить статическое свойство в интерфейсе typescript? Я ничего не нашел по этому поводу.
interface myInterface {
static Name:string;
}
Возможно ли это?
Вы не можете определить статическое свойство на интерфейсе в TypeScript.
Предположим, вы хотели изменить объект Date
, вместо того, чтобы пытаться добавить определения Date
, вы можете его обернуть или просто создать свой богатый класс даты, чтобы сделать материал, который Date
не сделать.
class RichDate {
public static MinValue = new Date();
}
Поскольку Date является интерфейсом в TypeScript, вы не можете расширять его классом с помощью ключевого слова extends
, что немного позорно, поскольку это было бы хорошим решением, если дата была классом.
Если вы хотите расширить объект Date, чтобы предоставить свойство MinValue
на прототипе, вы можете:
interface Date {
MinValue: Date;
}
Date.prototype.MinValue = new Date(0);
Вызывается с помощью:
var x = new Date();
console.log(x.MinValue);
И если вы хотите сделать его доступным без экземпляра, вы также можете... но он немного суетливый.
interface DateStatic extends Date {
MinValue: Date;
}
Date['MinValue'] = new Date(0);
Вызывается с помощью:
var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);
Следуйте @Duncan @Bartvds answer здесь, чтобы обеспечить работоспособный путь спустя годы.
На этом этапе после выпуска Typescript 1.5 (@Jun 15 '15) ваш полезный интерфейс
interface MyType {
instanceMethod();
}
interface MyTypeStatic {
new():MyType;
staticMethod();
}
может быть реализован таким образом с помощью декоратора.
/* class decorator */
function staticImplements<T>() {
return <U extends T>(constructor: U) => {constructor};
}
@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.
визуальный результат: ошибка компиляции с отсутствующим указанием на статический метод.
После реализации статического метода подсказка для метода отсутствует.
Компиляция прошла после того, как статический интерфейс и нормальный интерфейс выполнены.
Статические свойства обычно помещаются в (глобальный) конструктор для объекта, тогда как ключевое слово "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
Вы можете объединить интерфейс с пространством имен с тем же именем:
interface myInterface { }
namespace myInterface {
Name:string;
}
Но этот интерфейс полезен только для того, чтобы знать, что у него есть свойство Name
. Вы не можете его реализовать.
Я нашел способ сделать это (без декораторов) для моего конкретного случая использования.
Важной частью, которая проверяет статические элементы, является 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);
AFAIK, это невозможно.
К сожалению, это не старая добрая Java.
Да, это возможно. Вот решение
export interface Foo {
test(): void;
}
export namespace Foo {
export function statMethod(): void {
console.log(2);
}
}
Для тех, кто хочет добавить статический метод к встроенному объекту, например Date, легко
interface DateConstructor {
fromServerDate: any
}
И теперь Date.fromServerDate(appt.changeDate)
будет компилироваться отлично.