Sadece typcript arayüzünde statik bir özellik mi ilan etmek istiyorum ? Bununla ilgili hiçbir şey bulamadım.
interface myInterface {
static Name:string;
}
Mümkün mü?
Sadece typcript arayüzünde statik bir özellik mi ilan etmek istiyorum ? Bununla ilgili hiçbir şey bulamadım.
interface myInterface {
static Name:string;
}
Mümkün mü?
Yanıtlar:
TypeScript'te bir arabirimde statik özellik tanımlayamazsınız.
DateNesneyi, tanımlarına eklemeye çalışmak yerine değiştirmek istediğinizi varsayalım, Dateonu sarmalayabilir veya yapmayan şeyleri yapmak için zengin tarih sınıfınızı oluşturabilirsiniz Date.
class RichDate {
public static MinValue = new Date();
}
Tarih, TypeScript'te bir arabirim olduğundan, onu extendsanahtar sözcüğü kullanarak bir sınıfla genişletemezsiniz , bu biraz utanç verici, çünkü tarih bir sınıfsa bu iyi bir çözüm olurdu.
MinValuePrototip üzerinde bir özellik sağlamak için Date nesnesini genişletmek isterseniz şunları yapabilirsiniz:
interface Date {
MinValue: Date;
}
Date.prototype.MinValue = new Date(0);
Kullanılarak arandı:
var x = new Date();
console.log(x.MinValue);
Ve bir örnek olmadan kullanılabilir hale getirmek istiyorsanız, bunu da yapabilirsiniz ... ama bu biraz telaşlı.
interface DateStatic extends Date {
MinValue: Date;
}
Date['MinValue'] = new Date(0);
Kullanılarak arandı:
var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);
extendsanahtar kelimeyi kullanarak TS'deki arayüzleri genişletebilirsiniz . Bir arabirimi bir sınıfla genişletemezsiniz (statik bir özellik eklemek için yapmanız gereken).
Yıllar sonra uygulanabilir bir yol sağlamak için @ Duncan'ın @ Bartvds'ın cevabını buradan takip edin.
Typecript 1.5 yayınlandıktan sonra (15 Haziran 2015), yardımcı arayüzünüz
interface MyType {
instanceMethod();
}
interface MyTypeStatic {
new():MyType;
staticMethod();
}
dekoratör yardımı ile bu şekilde uygulanabilir.
/* 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() {}
}
13462 numaralı github açık sayısındaki yorumuma bakın .
görsel sonuç: Eksik bir statik yöntem ipucu ile derleme hatası.

Statik yöntem uygulandıktan sonra, yöntem eksik için ipucu.

Hem statik arayüz hem de normal arayüz yerine getirildikten sonra derleme geçti.

Arayüzü normal olarak tanımlayabilirsiniz:
interface MyInterface {
Name:string;
}
ama sadece yapamazsın
class MyClass implements MyInterface {
static Name:string; // typescript won't care about this field
Name:string; // and demand this one instead
}
Bir sınıfın statik özellikleri için bu arayüzü takip etmesi gerektiğini ifade etmek için biraz hile gerekir:
var MyClass: MyInterface;
MyClass = class {
static Name:string; // if the class doesn't have that field it won't compile
}
Sınıfın adını bile tutabilirsiniz, TypeScript (2.0) bunu önemsemez:
var MyClass: MyInterface;
MyClass = class MyClass {
static Name:string; // if the class doesn't have that field it won't compile
}
Statik olarak birçok arabirimden miras almak istiyorsanız, önce bunları yenisiyle birleştirmeniz gerekir:
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
}
Veya birleştirilmiş arayüzü adlandırmak istemiyorsanız şunları yapabilirsiniz:
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
}
Çalışma örneği
@staticImplements.
reply(msg: IBotMsg): Promise<IBotReply>
Statik özellikler genellikle nesnenin (genel) yapıcısına yerleştirilirken, "arabirim" anahtar sözcüğü nesnenin örnekleri için geçerlidir.
Sınıfı TypeScript'te yazıyorsanız, önceki cevap elbette doğrudur. Başkalarının, zaten başka bir yerde uygulanmış bir nesneyi tanımlıyorsanız, statik özellikleri içeren genel yapıcının şu şekilde bildirilebileceğini bilmelerine yardımcı olabilir:
declare var myInterface : {
new(): Interface;
Name:string;
}
Statik değiştiriciler bir tür üyesinde görünemez (TypeScript hatası TS1070). Bu yüzden görevi çözmek için soyut bir sınıf kullanmanızı tavsiye ederim:
Misal
// Interface definition
abstract class MyInterface {
static MyName: string;
abstract getText(): string;
}
// Interface implementation
class MyClass extends MyInterface {
static MyName = 'TestName';
getText(): string {
return `This is my name static name "${MyClass.MyName}".`;
}
}
// Test run
const test: MyInterface = new MyClass();
console.log(test.getText());
@ duncan'ın yukarıdaki new()statik türü belirleme çözümü , arayüzlerle de çalışır:
interface MyType {
instanceMethod();
}
interface MyTypeStatic {
new():MyType;
staticMethod();
}
implement?
MyType(olduğu gibi class Foo implements MyType) uygulayacaktır . Statik arayüz yalnızca mevcut JS kodunu açıklarken tanımlarda gerçekten kullanışlıdır.
Statik bir sınıf tanımlamak istiyorsanız (yani, tüm yöntemler / özellikler statiktir), şöyle bir şey yapabilirsiniz:
interface MyStaticClassInterface {
foo():string;
}
var myStaticClass:MyStaticClassInterface = {
foo() {
return 'bar';
}
};
Bu durumda, statik "sınıf" gerçekten yalnızca düz-ol'-js-nesnesidir ve tüm yöntemleri MyStaticClassInterface
Evet mümkün. İşte çözüm
export interface Foo {
test(): void;
}
export namespace Foo {
export function statMethod(): void {
console.log(2);
}
}
Foobir sınıf tanımını yerine getirmek için bir ad alanı kullanıyor ? Foo Sınıfı statMethod () 'u uygulayacağı yerde bu biraz hack gibi görünüyor, özellikle ad alanları artık kullanımdan kaldırıldı ...
waiting more feedback. Yani ya arayüze statik yöntemler eklenene kadar beklersiniz ya da bu şekilde yaparsınız.
export namespaceaslında sizin Sınıf uygulamanız mı? Bu işleri çok fazla büküyor gibi görünüyor. Acaba sınıflarda başka neler bozulur?
Burada bahsedilmeyen başka bir seçenek, değişkeni statik arabirimi temsil eden bir türle tanımlamak ve ona sınıf ifadesi atamaktır:
interface MyType {
instanceMethod(): void;
}
interface MyTypeStatic {
new(): MyType;
staticMethod(): void;
}
// ok
const MyTypeClass: MyTypeStatic = class MyTypeClass {
public static staticMethod() { }
instanceMethod() { }
}
// error: 'instanceMethod' is missing
const MyTypeClass1: MyTypeStatic = class MyTypeClass {
public static staticMethod() { }
}
// error: 'staticMethod' is missing
const MyTypeClass2: MyTypeStatic = class MyTypeClass {
instanceMethod() { }
}
Etki dekoratörlerle aynıdır , ancak dekoratörlerin yükü yoktur.
GitHub'da ilgili öneri / tartışma
Sen edebilirsiniz ad ile arayüz birleştirme aynı adı kullanarak:
interface myInterface { }
namespace myInterface {
Name:string;
}
Ancak bu arayüz yalnızca özelliğine sahip olduğunu bilmek yararlıdır Name. Uygulayamazsınız.
Bunu özel kullanım durumum için (dekoratörler olmadan) yapmanın bir yolunu buldum.
Statik üyeler için denetler olduğunu önemli bir parçası IObjectClassve kullanma cls: IObjectClass<T>içinde createObjectyöntemle:
//------------------------
// 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);
Typescript arayüzünde statik anahtar kelime desteklenmese function interfacede statik üyesi olan bir oluşturarak bunu başarabiliriz .
Aşağıdaki kodumdaFactory iki statik üye serialNumberve printSerial içeren bir işlev arabirimi oluşturdum .
// factory is a function interface
interface Factory<T> {
(name: string, age: number): T;
//staic property
serialNumber: number;
//static method
printSrial: () => void;
}
class Dog {
constructor(public name: string, public age: number) { }
}
const dogFactory: Factory<Dog> = (name, age) => {
return new Dog(name, age);
}
// initialising static members
dogFactory.serialNumber = 1234;
dogFactory.printSrial = () => console.log(dogFactory.serialNumber);
//instance of Dog that DogFactory creates
const myDog = dogFactory("spike", 3);
//static property that returns 1234
console.log(dogFactory.serialNumber)
//static method that prints the serial 1234
dogFactory.printSrial();
Kamil Szot'unki gibi bir çözüm uyguladım ve istenmeyen bir etkisi var. Bunu bir yorum olarak yayınlayacak kadar itibarım yok, bu yüzden birisinin bu çözümü denemesi ve bunu okuması durumunda buraya gönderiyorum.
Çözüm şudur:
interface MyInterface {
Name: string;
}
const MyClass = class {
static Name: string;
};
Ancak, bir sınıf ifadesi kullanmak tür MyClassolarak kullanmama izin vermiyor . Şöyle bir şey yazarsam:
const myInstance: MyClass;
myInstancetürden olduğu ortaya çıktı anyve editörüm şu hatayı gösteriyor:
'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?ts(2749)
Sınıfın statik kısmı için arayüzle elde etmek istediğimden daha önemli bir yazımı kaybediyorum.