上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

typescript 静态侧与实例侧与typeof class

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5085

    回帖

    5959

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5959

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-27 22:46:14 | 显示全部楼层 | 阅读模式

    前文

    因为这个中文资料还是比较少的
    所以大概查阅了一下
    无法保证正确性
    仅为个人理解的翻译
    出处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类似的错误实在太容易出现了
    我还能说什么呢
    只有撒花了

    结语

    撒花~

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情

    2023-12-8 22:55
  • 签到天数: 37 天

    [LV.5]常住居民I

    15

    主题

    145

    回帖

    153

    积分

    荣誉开发者

    积分
    153

    荣誉开发者

    发表于 2022-6-28 20:19:58 | 显示全部楼层
    摸鱼中
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5085

    回帖

    5959

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5959

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-28 21:27:56 | 显示全部楼层
    执念e1 发表于 2022-6-28 20:19
    https://www.tslang.cn/docs/handbook/interfaces.html

    yep
    文档写的太简略了。。。
    我就是看到这里感觉不懂又查的
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    2023-12-8 22:55
  • 签到天数: 37 天

    [LV.5]常住居民I

    15

    主题

    145

    回帖

    153

    积分

    荣誉开发者

    积分
    153

    荣誉开发者

    发表于 2022-6-28 22:08:26 | 显示全部楼层
    李恒道 发表于 2022-6-28 21:27
    yep
    文档写的太简略了。。。
    我就是看到这里感觉不懂又查的

    同,不过我后面就没再多看了
    摸鱼中
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5085

    回帖

    5959

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5959

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-28 22:17:09 | 显示全部楼层
    执念e1 发表于 2022-6-28 22:08
    同,不过我后面就没再多看了

    ts文档太鬼了。。。
    基本一章下来卡半章
    能流行起来才有鬼了
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表