【问题标题】:TypeScript bindings for class not working?类的 TypeScript 绑定不起作用?
【发布时间】:2020-05-26 09:15:08
【问题描述】:

我有一个定义文件,我们称之为someclass.d.ts,它看起来或多或少像这样:

declare class SomeClass {
    static write : {
        doThing(name: string) : string
    }

    static get : {
        doThing2(count: number): string
    }
}

这与someclass.ts中的实际类匹配

export default class SomeClass {
    static write = {
        doThing(name) {
            return "foo1";
        }
    }

    static get = {
        doThing2(count) {
            return "foo2";
        }
    }
}

然后在我的mainThing.ts 中,它实际上使用了SomeClass:

/// <reference types="./someclass" />
import SomeClass from './someclass.ts';
SomeClass.write.doThing("dummyexample");

如果我在 VSCode 中将鼠标悬停在 mainThing.ts/someclass.ts 中的 doThing 上,它的行为就像一切都是隐含的任何类型,这告诉我我做错了某事。我只是不知道是什么。

我猜我对这些类成员块的声明是错误的,但我不确定正确的做法是什么;尝试做static write = { 似乎让它寻找函数体......

我做错了什么?谢谢!

编辑:我知道我不需要有一个单独的定义文件,但我想以可读代码的名义这样做。 doThing 的 real 签名看起来更像

doThing({ name, email, password, p4, p5, p6 }
    : { name: string, email: string, password: string, p4: string, p5: number, p6: string }) 
    : Type1<Type2<Type3>>

编辑 2:另外,SomeClass 实际上不需要是一个类...也许 TypeScript 命名空间(或其他东西)更合适?我主要只是试图以一种不会压倒一切的方式组织大量实用程序方法。出于这个原因,一切都是故意静态的;当 SomeClass 没有任何状态时,实例化它是没有意义的。

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    .d.ts 声明文件用于对.js 文件进行类型注释,而不是.ts 文件。

    我可以看到您在这里尝试使用 Java 约定。事情是 JS class 与 Java class 完全不同。 TS 是为 JS 设计的,所以它不会像你期望的那样为你服务。虽然.d.ts 可以和.ts 文件一起使用,但是涉及到class 的用法非常繁琐,超出了可读代码的目的。

    我对您的问题的建议是使用纯对象而不是 class-static 对,因为 JS class 确实是对象的语法糖。

    someclass.d.ts

    declare interface SomeClass {
      write: {
        doThing(name: string): string;
      };
    
      get: {
        doThing2(count: number): string;
      };
    }
    

    someclass.ts

    const SomeClass: SomeClass = {
      write: {
        doThing(name) {
          return "foo1";
        }
      },
    
      get: {
        doThing2(count) {
          return "foo2";
        }
      }
    };
    
    export default SomeClass;
    

    ma​​inThing.ts

    import SomeClass from './someclass.ts';
    SomeClass.write.doThing(1);
    // [TS ERROR] Argument of type '1' is not assignable to parameter of type 'string'.
    

    旁注:

    我之前说过涉及class 的用法很乏味。如果您真的想使用class-static,请按照以下步骤操作:

    someclass.d.ts

    declare abstract class SomeAbstractClass {
      static write: {
        doThing(name: string): string;
      }
    }
    

    someclass.ts

    export default class SomeClass extends SomeAbstractClass {
      static write = {
        // you still need to re-write the function signature in class impl
        doThing(name: string) {
          return "foo1";
        }
    
        // all it does is just to warn you when you accidentally write:
        doThing(name: number) { // ERROR: should be string not number
          return "foo1";
        }
      }
    }
    

    您不能使用class SomeClass implements SomeClassInterface,cus implements 关键字只控制类的实例端,而不是静态端。

    【讨论】:

    • 奇怪的是 typescript 会让你任意注释 .js 文件,而不是 .ts 文件。 Cypress.io 之类的交叉点有点奇怪——您可以在 .js 文件中添加自定义 Cypress 命令,它们会显示在您的 .ts 文件中。但是,如果您将该 js 文件重命名为 .ts... 不!从接口继承是有道理的,但这似乎是一个奇怪的限制。
    • 欢迎来到jsland。整个生态系统建立在大量遗留物之上,人们通过点击刷新按钮来解决问题。我想说 TS 团队在整合如此强大的语言扩展方面做得很好。它并不完美,但考虑到 JS 的糟糕程度,这几乎是一个奇迹。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2014-06-13
    相关资源
    最近更新 更多