前文
因为这个中文资料还是比较少的
所以大概查阅了一下
无法保证正确性
仅为个人理解的翻译
出处https://stackoverflow.com/questions/58399613/what-is-exactly-the-static-side-and-the-instance-side-in-typescript
正文
计算机可能命名是极其困难的
在Typescript中,我们通常使用相同的名字同时表示类的构造函数,以及类的类型
前者在运行时存在
而后者仅在编译前存在
所以在
class Foo { }
const foo: Foo = new Foo();
有一个名为Foo的类构造函数,可以构造出Foo的实例类型
这种情况有一些类似于
乐高同时指代乐高工厂以及乐高工厂生产的乐高积木
丰田同时指代丰田工厂以及丰田工厂生产的丰田汽车
我们说乐高制造和销售乐高积木以及丰田制造和销售丰田汽车
通常没有任何的问题
但是当聊到Foo构造foo实例是极其令人困惑的
当我们谈论到一个类的时候
我们可能在讨论他的静态侧(static aspects/static side),他与构造函数有关
通常是单数,因为构造函数只有一个,对于所有实例类型都是相同的
或者我们可能讨论的是实例侧(instances aspects/instances side)
他与类的实例有关,通常是复数,因为单个构造函数
可以创造出许许多多的实例
每个实例都与其他实例具有不同的属性以及状态
从类型系统的角度而言,类型Foo代表实例的属性
如果我们想要获取静态侧的类型,需要使用typeof Foo语句莱获取静态侧类型
所以
Foo是实例侧的类型
typeof Foo是静态侧类型
举个栗子
class Foo {
instanceProp: string;
constructor(constructorArgument: string) {
this.instanceProp = constructorArgument;
}
instanceMethod(): void {
console.log("Instance method called on " + this.instanceProp)
}
static staticProp: string = "Static Thing";
static staticMethod(): void {
console.log("Static method called on " + this.staticProp)
}
}
Foo类具有一个静态侧和一个实例侧
静态方面Foo是与构造函数有关的东西
包括
构造函数本身,类型为{new(constructorArgument: string): Foo}
属性staticProp,类型为string
方法staticMethod,类型为{(): void}
这种类型称之为typeof Foo
但你也可以使用另一种方式,如定义它的接口,如下所示
interface StaticSideOfFoo {
new(constructorArgument: string): Foo;
staticProp: string;
staticMethod(): void;
}
实例方面Foo,是与构造函数产生的实例有关的东西,包括
属性instanceProp,类型为string
方法instanceMethod,类型为{(): void}
这种类型称为Foo,我们也可以定义自己的接口
interface InstanceSideOfFoo {
instanceProp: string;
instanceMethod(): void;
}
其中的区别如下所示
const foo1 = new Foo("Number 1");
console.log(foo1.instanceProp); // Number 1
foo1.instanceMethod(); // Instance method called on Number 1
const foo2 = new Foo("Number 2");
console.log(foo2.instanceProp); // Number 2
foo2.instanceMethod(); // Instance method called on Number 2
console.log(Foo.staticProp); // Static Thing
Foo.staticMethod(); // Static method called on Static Thing
foo1和foo2是两个实例Foo,不能直接访问构造函数的签名,staticProp,staticMethod等静态侧内容
new foo1("oops"); // error!
foo1.staticProp; // error!
foo1.staticMethod(); // error!
同时构造函数Foo无法访问实例内容instancePropor或instanceMethod
Foo.instanceProp; // error!
Foo.instanceMethod(); // error!
实例foo1和foo2都具有类型Foo,类似于接口InstanceSideOfFoo
而构造函数Foo具有类型typeof Foo,类似接口StaticSideOfFoo
我们可以在这里进行验证
const instanceSideOfFoo: InstanceSideOfFoo = foo1; // okay
const instanceSideOfFooOops: InstanceSideOfFoo = Foo; // error!
const staticSideOfFoo: StaticSideOfFoo = Foo; // okay
const staticSideOfFooOops: StaticSideOfFoo = foo1; // error!
实例侧和静态侧具有不同的属性和不同的用图
如果要创造一个接受Foo构造函数的函数,那么我们要使用
typeof Foo/StaticSideOfFooor/new (x: string)=>Foo
如果我们要创建一个接受实例的函数,我们需要使用
Foo/InstanceSideOfFoo/{instanceProp: string}
如果没有这样的区别
你可能会因为孩子想要乐高而买下乐高公司
或想买一辆汽车而成为丰田的股东
Typescript类似的错误实在太容易出现了
我还能说什么呢
只有撒花了
结语
撒花~