【问题标题】:how forcing a type instance instead of typeof in typescript如何在打字稿中强制使用类型实例而不是 typeof
【发布时间】:2021-06-16 22:12:48
【问题描述】:

如何通过强制将type 导出为实例来导出它。

我尝试了很多方法,我只找到了一个解决方案,创建一个静态 getter,但我想删除我的静态 getter。

这里的上下文: 我想从 $A.A 那里导出 A 的一个实例类型,仅供参考。


export const $A = (() => {
    class A {
        static get default() {
            return A.create();
        }
        static create() {
            return new A();
        }
        constructor() {}
    }

    return { A };
})();

我尝试了很多方法,这里有 7 个!没有人按照 1 的方式工作!但这是因为我在 js 类中添加了一个静态 getter。

export type _1 = typeof $A.A.default;
export type _2 = typeof new $A.A;
export type _3 = typeof $A.A.create();
export type _4 = typeof  $A.A();
export type _5 = typeof $A['A'];
export type _6 =  $A.A;
export type _7 = typeof new ()=>$A.A;

// example somewhere in the project, i want tell A should be a instance and not a typeof!
function foo(A:_6)

那么在 ts 类型中模拟实例以导出到某处仅用于 typage 的语法是什么。 我的项目是在 js 中,但使用 ts 只是为了帮助 tsserver 在他不理解我的 refs 时。

  • 所以它仅用于我的 ide 中的 Intelisence,而不用于生成 ts=>js。

【问题讨论】:

  • 这里的泛型到底是什么?我在任何地方都看不到类型参数。
  • 对不起,翻译小姐,我删除了generic word
  • 参见例如this github issue,或this qeustion。您应该得到的相关错误消息是“Exported variable '$A' has or is using private name 'A'.(4025)”。
  • 这与这个问题无关,但是上面的那个人找到了这个工具很好。也感谢您的宝贵时间。

标签: javascript typescript visual-studio-code type-conversion


【解决方案1】:

初步说明:这里的class A 代码缺少任何实例结构(没有属性或方法)。所有非空值都可以分配给该实例类型;请参阅this FAQ entry 了解更多信息。为了避免这种怪异,我在示例类中添加了一个属性:

const $A = (() => {
    class A {
        static get default() {
            return A.create();
        }
        static create() {
            return new A();
        }
        constructor() { }
        someStructure = 123; // add structure here
    }

    return { A };
})();

现在编译器可以判断 {someRandomThing: 123} 与您在命名时遇到问题的 A 类型不兼容。


您可能想使用the InstanceType<T> utility type 提取构造签名的返回类型:

type A = InstanceType<typeof $A.A>

您可以使用conditional type inference 自己编写:

type AlsoA = typeof $A.A extends new (...args: any) => infer I ? I : never;

或者,您可以使用我们在条件类型存在之前必须使用的方法:TypeScript 假设类的 prototype 属性与其实例类型相同。这不是真的,因为原型通常只包含方法而不包含其他属性。但无论如何你都可以使用它:

type AlsoAlsoA = typeof $A.A.prototype;

其中任何一个都应该产生相同的类型。


让我们确保它有效:

function foo(a: A) { }

foo($A.A.create()) // okay
foo({ someRandomThing: 123 }) // error 
// Argument of type '{ someRandomThing: number; }' is 
// not assignable to parameter of type 'A'.

看起来不错!

Playground link to code

【讨论】:

  • 非常感谢,export type Entity = InstanceType&lt;typeof $Entity.Entity &gt; ; 工作就像一个魅力!我在文档中搜索了很长时间但没有成功。 “缺少任何实例结构”,当然,我删除所有以专注于问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2019-08-04
  • 2021-07-20
相关资源
最近更新 更多