我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。

interface myInterface {
  static Name:string;
}

这可能吗?


当前回答

可以使用相同的名称将接口和命名空间合并:

interface myInterface { }

namespace myInterface {
  Name:string;
}

但是这个接口只有知道它的属性Name才有用。你不能实现它。

其他回答

静态属性通常放在对象的(全局)构造函数上,而“interface”关键字适用于对象的实例。

如果你用TypeScript编写类,前面给出的答案当然是正确的。如果你描述的是一个已经在其他地方实现的对象,那么包含静态属性的全局构造函数可以这样声明:

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

我的解决方案对于添加额外静态构造函数的用例非常有效。我已经测试过了,它通过了所有的测试。如果有人发现有问题,请告诉我。

我做了一个泛型类型,它接受接口和静态接口。

它适用于具体类和抽象类。

我使用条件类型来设计它,这样所有的错误都可以传播 到实现接口的类,而不是接口本身。

注意:错误传播允许vscode快速修复(实现所有方法)。唯一的缺点是你必须自己应用static关键字,因为没有快速修复这个错误的方法。

的接口:

type Class<T = any> = new (...args: any[]) => T;
type AbstractClass<T = any> = abstract new (...args: any[]) => T;

type Interface<C extends Class<InstanceType<C>> | AbstractClass<InstanceType<C>>, SI, I = {}> = 
    C extends Class<InstanceType<C>> 
    // ConcreteClass
    ? InstanceType<C> extends I 
        ? C extends (SI & Class<InstanceType<C>>)
            ? (InstanceType<C> & I)
            : (SI & Class<InstanceType<C>>) // Indicate StaticInterface Error
        : I // Indicate Interface Error
    // AbstractClass
    : InstanceType<C> extends I 
        ? C extends (SI & AbstractClass<InstanceType<C>>)
            ? (InstanceType<C> & I)
            : (SI & AbstractClass<InstanceType<C>>) // Indicate StaticInterface Error
        : I // Indicate Interface Error

用法:

interface MyInterface {
    instanceMethod(): number;
}

interface MyStaticInterface {
    staticMethod(): number;
}
 
class MyClass implements Interface<typeof MyClass, MyStaticInterface, MyInterface> {
    static staticMethod(): number {
        return 50;
    }

    instanceMethod(): number {
        return 100;
    }

    static otherStatic() {
        return "HELLO"
    }

    otherInstance() {
        return "GOODBYE"
    }
}

abstract class MyClass1 implements Interface<typeof MyClass1, MyStaticInterface, MyInterface> {
    static staticMethod(): number {
        return 50;
    }


    instanceMethod(): number {
        return 20;
    }

    static otherStatic() {
        return "HELLO"
    }

    otherInstance() {
        return "GOODBYE"
    }

    abstract abstractMethod() : number;

}

这里没有提到的另一个选项是用表示静态接口的类型定义变量,并为其分配类表达式:

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() { }
}

效果与使用装饰器的应答相同,但没有装饰器的开销

操场上

GitHub上的相关建议/讨论

我执行了一个类似Kamil sot的解决方案,但却产生了意想不到的效果。我没有足够的声誉来发表这条评论,所以我把它贴在这里,以防有人正在尝试这个解决方案并阅读这篇文章。

解决方案是:

interface MyInterface {
    Name: string;
}

const MyClass = class {
    static Name: string;
};

但是,使用类表达式不允许我使用MyClass作为类型。如果我这样写:

const myInstance: MyClass;

myInstance的类型是any,我的编辑器显示以下错误:

'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?ts(2749)

我最终失去了一个比我想通过类的静态部分的接口实现的更重要的类型。

瓦尔使用装饰器的解决方案避免了这个陷阱。

这里有一个相当简单的方法:

interface MyClass {
    new (): MyClassInstance;
    staticMethod(): string;
}

interface MyClassInstance {
    instanceMethod(): string;
}

const Class: MyClass = class {
    static staticMethod() {
        return "This is a static method";
    }
    instanceMethod() {
        return "This is an instance method";
    }
}

Class.staticMethod();

// Has type MyClassInstance
const instance = new Class();
instance.instanceMethod();

请注意,这并不允许您像通常那样让类扩展接口,但对于许多情况来说,这已经足够好了。