使用声明合并构建类型(Typescript)

Use declaration merging to build a type (Typescript)

我用过declaration merging如下

function barfoo(): void { /* magic */ }
namespace barfoo {
    export let maz: Array<string> = [];
}

但问题是,我该如何使用它。比如我这样使用

function doIt(cb: barfoo): void {
    cb.maz = [10];
    cb();
}

打字稿抱怨:Cannot find name 'barfoo'.

DEMO

关于如何修复类型的任何建议(不使用 any :)?

更新:我想出了如何创建这种类型的新函数

let x: { (): Array<string>; maz: Array<string>; };

x = (() => {
    var _x : any = function () { };
    _x.maz = [];
    return _x;
})();

let y: { (): void; maz: Array<string> } = (() => {
    let _y: any = function fake(): Array<string> {
        return ((cb: any): Array<string> => {
            return cb.maz;
        })(fake);
    }
    _y.maz = [];
    return _y;
})();

DEMO

但是,如您所见,第二个示例非常复杂。这是正确的方法还是可以简化?

您的问题是 barfoo 是一个 ,但在您对 doIt() 的定义中,您错误地将其视为 输入。所有值 都有 类型,但值的名称很少是其类型的名称。如果我做 let x = 3; 那么 x 是一个值,但它的类型是 number,而不是 x

从您的代码看来,您希望能够将值 barfoo 传递给函数。 (为什么你想做这样的事情是你的事,但如果你只打算将那个值传递给函数,你可能想要考虑根本不让它成为参数。取决于你,虽然.) 所以 cb 参数应该声明为 barfoo 的类型,不管它是什么。通过检查,您可以看到它类似于 { (): void; maz: string[] }。 但幸运的是,TypeScript 允许您使用重用关键字 typeoftype query 快速获取命名值的类型。 barfoo 的类型就是 typeof barfoo:

function doIt(cb: typeof barfoo): void {
    cb.maz = [10];  // error, hey 10 is not a string
    cb();
}

这有效,甚至可以为您捕获另一个错误。希望有所帮助;祝你好运!


更新

如果你想创建更多与 barfoo 相同类型的对象,即:一个可调用函数(没有参数并返回 void),它也有一个 maz 属性 包含一个字符串数组,最直接的方法是使用所有参数类型的 Object.assign(), which merges all properties into the first argument and returns it as the intersection。像这样:

const barfoo2 = Object.assign(
  function() {
    // function body here
  },
  {maz: ["some","stuff"]}
);

doIt(barfoo2); // works

祝你好运!