TypeScript 无法指定继承自T并实现IFooable接口的类的返回类型,

thigvfpy  于 4个月前  发布在  TypeScript
关注(0)|答案(6)|浏览(124)

TypeScript版本: 2.2.1 / nightly (2.2.0-dev.201xxxxx)

代码

// A *self-contained* demonstration of the problem follows...
export type Constructor<T> = new (...args: any[]) => T;
export interface IFooable { FooProp: string; }
export function FooableMixin<T extends Constructor<{}>>(Base: T) {
    return class extends Base implements IFooable {
        FooProp: string;
        constructor(...args: any[]) {
            super(...args);
        }
    }
}
export class BaseBar { BarProp: string = "baz"; }
export class FooableBar extends FooableMixin ( BaseBar ) {}
let foobar = new FooableBar();
foobar.FooProp = foobar.BarProp; 
/* This is ok since FooableBar extends an Anonymous class inheriting from BaseBar and implementing IFooable */

如果我在tsconfig.json中打开"declaration": true,这个构造会破坏,因为匿名类被视为私有类型而不是导出类型(错误TS4060),这很自然,因为它是匿名的。我们需要一种方法来描述类作为返回类型。

预期行为:

一个d.ts文件,其中包含一个类型声明,用于定义Mixin函数Fooable的匿名类返回类型,如下所示:

declare function Fooable(T extends Constructor<{}>): (class extends T implements IFooable);

实际行为:

在使用"declaration"标志编译时出现TS4060错误。如果将匿名类返回值转换为T或T,接口将丢失。

8gsdolmq

8gsdolmq1#

#14075#14597 的重复问题,目前解决方法是:

  1. 在 Mixin 函数中添加返回类型:T & ICtor,以消除 TS4060 错误。
  2. 在扩展之前声明联合类型为 const。
    这使得 mixins 的使用变得更加繁琐。
o75abkj4

o75abkj42#

我想知道这是否可以用#6606解决。

zc0qhyus

zc0qhyus3#

类表达式不允许出现在类型位置。修复方法是允许它,然后在声明发射器中发出它。

nhjlsmyf

nhjlsmyf4#

部分解决方法是在函数外部使用预先定义的类型声明返回类型,但非类类型不能有protected成员,因此无法从mixin类继承受保护的成员(除手动转换外)。

gdrx4gfi

gdrx4gfi5#

好的!
看起来最近发布的版本(3.6.4?)已经修复了一些问题,使得我的库可以在package.json中指定"types": "./src/index.ts"(直接指向一个普通的TS文件,而不是一个.d.ts声明文件!),没有任何问题。
这使得我可以在tsconfig.json中设置"declaration": false,并依赖实际的代码进行类型检查,从而允许推断返回类型!
这确实意味着我需要运送源TS文件,而不仅仅是声明文件。

oxiaedzo

oxiaedzo6#

我也遇到了声明和混入的问题。运输源代码是一个选择,但我更倾向于其他方式。有人知道如何实现吗?

相关问题