【问题标题】:Typescript declarations for javascript filejavascript文件的打字稿声明
【发布时间】:2018-03-11 21:12:55
【问题描述】:

我正在使用一个混合了 javascript 和 typescript 的项目。 可以使用 - declare module 轻松创建模块的声明文件。但是如何为当前文件夹中的 javascript 文件创建声明?

前 -

player.js -
var Player = function() {};
Player.prototype.validate = function() {};

如何创建声明以便可以在 typescript 中扩展它。我想做这样的事情-

player.ts -
let Player = require('./player');
Player.prototype.login = function() {
    this.validate();
}

我知道上面的代码可以通过将 Player type 设置为 any 来工作,但我无法进行类型检查。

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    您可以在 TypeScript 文件中创建界面并将其设置为 Player 的类型。

    interface IPlayer {
      validate();
    }
    
    let Player: IPlayer = require('./player');
    
    Player.prototype.login = function() {
        this.validate();
    }

    【讨论】:

    • 错误 TS2339:“IUser”类型上不存在属性“原型”。
    【解决方案2】:

    在这里扩展 Sabbir 的答案(cmets 中没有足够的空间)

    interface IPlayer { 
      validate(): void
      login():void
    }
    

    旧js代码

    var Player = function () { }
    Player.prototype.validate = function() {}
    

    在ts项目中使用

    // import / require here, left out for brevity
    Player.prototype.login = function() {
        this.validate()
    }
    

    创建播放器 - 登录和验证现在具有自动完成功能

    let p: IPlayer = new Player()
    p.login()
    p.validate()
    

    【讨论】:

    • 但在播放器功能中无法自动完成
    • 我不知道您的确切项目用例,但我个人更喜欢创建一个 Typescript 类并复制 JS 方法。然后您将获得完整的代码完成。检查编辑
    • 这是一个非常大的类,我不想混合使用 javascript 和 typescript 代码。
    【解决方案3】:

    TypeScript 不理解原型语法/构造函数:不会有智能感知。它更喜欢 ES6 类。

    JavaScript Player 构造函数等价于这个 TypeScript 类定义:

    // -- player.d.ts --
    declare class Player {
      validate(): void;
    }
    

    然后,要向Player 类添加方法,有几个选项:

    1. 更多的 TypeScript 惯用方式:类继承或类组合
    2. 在 TypeScript 中继续使用原型语法并仍然获得智能感知的折衷方案:外观接口

    代码示例:

    // -- authenticated-player.ts --
    import { Player } from './player'; 
    
    // Option #1a: class inheritance
    class AuthenticablePlayer extends Player {
      login() {
        this.validate();
      }
    }
    
    const p1a = new AuthenticablePlayer();
    p1a.login();
    
    // Option #1b: class composition + delegation
    class AuthenticablePlayerB {
      private player = new Player(); 
    
      login() {
        this.validate();
      }
    
      validate() {
        this.player.validate();
      }
    }
    
    const p1b = new AuthenticablePlayerB();
    p1b.login();
    

    --

    // Option #2: prototype extension + facade interface + type assertion
    const Player: any = require('./player');
    
    Player.prototype.login = function() {
      this.validate();
    }
    
    interface IPlayer {
      login(): void;
      validate(): void;
    }
    
    function createPlayer(): IPlayer {
      return new Player();
    }
    
    const p2 = createPlayer();
    p2.login();
    

    【讨论】:

    • 更多关于declare classinterface的区别,见stackoverflow.com/a/14348084/1704166
    • 希望有一种方法可以添加到当前类而不扩展它。但我想我必须延长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 2017-02-16
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    相关资源
    最近更新 更多