编译时可能不存在的 Typescript 调用函数

Ed *_*ans 7 typescript

我正在尝试编写一个库来检查回调函数,然后在准备好时调用它。这个想法是,您可以异步包含 JS,然后在加载它时,它将检查回调并执行它。

我正在使用打字稿。以下 JS 可以运行,但无法在 TS 中编译

if(typeof myFramework.ready === 'function') {
    myFramework.ready();
}
Run Code Online (Sandbox Code Playgroud)

然后使用该库的开发人员可以执行以下操作:

var myFramework = myFramework || {}; // As the framework wont exists
myFramework.ready = function(){//Execute developer's code};
Run Code Online (Sandbox Code Playgroud)

但是,使用 TypeScript 我收到类型错误:“typeof myFramework”类型上不存在属性“ready” - 这并不奇怪。如果我执行以下操作,它会编译:

interface Window {
    ready(): void;
}

if(typeof window.ready === 'function') {
    window.ready();
}
Run Code Online (Sandbox Code Playgroud)

但这意味着向窗口对象添加更多的数据。我想调用全局的ready()方法很可能是一个失败点!

您将如何实现这一目标?


感谢@james-crosswell - 因为我在单独的文件中有类,所以具有 Ajax 处理位的文件看起来像这样:

module MyFramework {
    export interface IMyFramework {
        ready? : () => any;
    }

    export class HasLoaded implements IMyFramework {
        doReady = (framework: IMyFramework) => {
            if(typeof framework.ready === 'function') {
                framework.ready();
            }
        }
    }

    var newHost: HasLoaded = new HasLoaded();
    newHost.doReady(MyFramework);
}
Run Code Online (Sandbox Code Playgroud)

我可能正在重新思考让我来到这里的逻辑,但这是一个单独的问题!

jea*_*sti 10

myFramework.ready?.();
Run Code Online (Sandbox Code Playgroud)

我认为是最紧凑的并且类似于 C# 语法。它使用可选的链接运算符(?.)

===============

对其他答案的一些评论:

为什么不是这个?

if (!!myFramework.ready) {
    myFramework.ready();
}
Run Code Online (Sandbox Code Playgroud)

(经典的双感叹号构造——第一个感叹号将“未定义”转换为 true,第二个感叹号将其返回为 false(因此将“未定义”转换为有效的 false 布尔值)

请注意:ESLint不喜欢这种构造:

myFramework.ready && myFramework.ready();
Run Code Online (Sandbox Code Playgroud)

它说:“预期有一个赋值或函数调用,但看到的是一个表达式”


Jam*_*ell 0

您当然可以在 Typescript 的模块中声明/导出接口...但它们对您的框架的用户没有任何用处,除非这些用户也使用 Typescript (并且拥有您的框架的 tsd)。

有了这个警告,上面 @gilamran 的答案的以下变体在Typescript Playground上有效:

module MyModule {
    export interface IMyFramework {
        ready? : () => any;
    }

    class MyFramework implements IMyFramework {
    }

    class YourFramework implements IMyFramework {
        ready = () => {
            alert("You're ready");
        }
    }

    export class Host {
        doReady = (framework: IMyFramework) => {
            if(typeof framework.ready !== 'undefined') {
                framework.ready();
            }           
        }
    }

    var host: Host = new Host();
    host.doReady(new MyFramework());
    host.doReady(new YourFramework());

}
Run Code Online (Sandbox Code Playgroud)