如何在打字稿中强制使用类型实例而不是 typeof

时间:2021-03-19 13:39:23

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

如何通过将 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。

enter image description here

1 个答案:

答案 0 :(得分:2)

初步说明:此处的 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