特定 javascript 实例化模式的正确打字稿定义是什么
What is the right typescript definition for a specific javascript instantiation pattern
我目前正在研究 Paper.js
库打字稿定义,但我无法找到正确的方法来记录 API.
的某些部分
情况可以简化为以下情况:假设我们有一个 Animal
class,它有一个用作自定义构造函数的静态 属性 Dog
对于 class:
var Animal = function(type) {};
Animal.Dog = function() {
return new Animal('dog');
};
Animal
实例可以通过两种方式构建:
var dog = new Animal('dog');
或:
var dog = new Animal.Dog();
在这两种情况下,我都需要将 dog
变量的类型推断为 Animal
。
我第一次尝试:
declare class Animal
{
constructor ( type )
static Dog (): Animal
}
但 TSLint 失败并显示错误:"Only a void function can be called with the 'new' keyword.",因为 Animal.Dog()
函数 return 类型是 Animal
.
如果我将 Animal.Dog()
的 return 类型设置为 void
:
declare class Animal
{
constructor ( type )
static Dog (): void
}
TSLint 通过,但我得到 void
作为推断类型...
所以我尝试了另一种方法:
declare class Animal
{
constructor ( type )
}
declare namespace Animal
{
export class Dog extends Animal
{
constructor()
}
}
有了这个,TSLint 通过了,但是在以下情况下:
var dog = new Animal.Dog();
dog
变量的推断类型是 Animal.Dog
而不是我想要的 Animal
。
这不是什么大问题,因为 Animal.Dog
type extends Animal
但是库中没有 Animal.Dog
,所以我发现这个解决方法误导了用户。
有谁知道处理这种情况的更好方法吗?
编辑
从@stramski 解决方案中阐述,我添加到问题中,事实上 Animal.Dog
可以有多个签名(例如 Animal.Dog()
和 Animal.Dog(color)
),我的目标是记录它们分开。
像这样的事情怎么样:
declare class Animal
{
constructor ( type )
static Dog : (new () => Animal)
}
编辑
由于存在重载的构造函数,因此输入略有不同:
declare class Animal
{
constructor ( type )
static Dog : (new () => Animal) & (new (color) => Animal)
}
因为你是子类化.. 保持事情干净简洁很重要。上面写的方式,可以看到Dog是被造出来的动物,但是跟动物没有什么区别。在某些情况下,有些变量或方法会被覆盖。话虽这么说,我发现如果你实现类似于以下内容的东西会更好:
class Animal {
constructor(){}
communicate() { return "Makes Noise"; }
}
class Dog extends Animal {
constructor(){
super();
}
communicate() { return "Barks"; }
}
从那里您可以覆盖方法或变量,以便正确区分狗与动物,与其他动物子 类。
我目前正在研究 Paper.js
库打字稿定义,但我无法找到正确的方法来记录 API.
情况可以简化为以下情况:假设我们有一个 Animal
class,它有一个用作自定义构造函数的静态 属性 Dog
对于 class:
var Animal = function(type) {};
Animal.Dog = function() {
return new Animal('dog');
};
Animal
实例可以通过两种方式构建:
var dog = new Animal('dog');
或:
var dog = new Animal.Dog();
在这两种情况下,我都需要将 dog
变量的类型推断为 Animal
。
我第一次尝试:
declare class Animal
{
constructor ( type )
static Dog (): Animal
}
但 TSLint 失败并显示错误:"Only a void function can be called with the 'new' keyword.",因为 Animal.Dog()
函数 return 类型是 Animal
.
如果我将 Animal.Dog()
的 return 类型设置为 void
:
declare class Animal
{
constructor ( type )
static Dog (): void
}
TSLint 通过,但我得到 void
作为推断类型...
所以我尝试了另一种方法:
declare class Animal
{
constructor ( type )
}
declare namespace Animal
{
export class Dog extends Animal
{
constructor()
}
}
有了这个,TSLint 通过了,但是在以下情况下:
var dog = new Animal.Dog();
dog
变量的推断类型是 Animal.Dog
而不是我想要的 Animal
。
这不是什么大问题,因为 Animal.Dog
type extends Animal
但是库中没有 Animal.Dog
,所以我发现这个解决方法误导了用户。
有谁知道处理这种情况的更好方法吗?
编辑
从@stramski 解决方案中阐述,我添加到问题中,事实上 Animal.Dog
可以有多个签名(例如 Animal.Dog()
和 Animal.Dog(color)
),我的目标是记录它们分开。
像这样的事情怎么样:
declare class Animal
{
constructor ( type )
static Dog : (new () => Animal)
}
编辑
由于存在重载的构造函数,因此输入略有不同:
declare class Animal
{
constructor ( type )
static Dog : (new () => Animal) & (new (color) => Animal)
}
因为你是子类化.. 保持事情干净简洁很重要。上面写的方式,可以看到Dog是被造出来的动物,但是跟动物没有什么区别。在某些情况下,有些变量或方法会被覆盖。话虽这么说,我发现如果你实现类似于以下内容的东西会更好:
class Animal {
constructor(){}
communicate() { return "Makes Noise"; }
}
class Dog extends Animal {
constructor(){
super();
}
communicate() { return "Barks"; }
}
从那里您可以覆盖方法或变量,以便正确区分狗与动物,与其他动物子 类。