在类型文件中为 JavaScript 声明接口

Declare Interfaces in typings file for JavaScript

项目信息

我正在开发一个使用 .d.ts 文件的 JavaScript 项目。这是我之前提出的问题的后续问题,因此您可以查看有关该项目的更多信息

问题

虽然我通常可以从类型文件中提取函数,但我无法提取空的或仅由接口组成的接口或名称空间。我通过为每个接口创建一个 const 实现并在注释中使用 @typeof ConstantImplementation 暂时解决了这个问题。请参阅下面的示例:

// Typings File
export namespace test {
    export interface ITest {
        foo: string;
        bar: number;
    }
    export const Test: ITest;
}

// JS File
if (undefined) var {Test: ITest} = require("globals.d.ts").test; 
// Above line shows `unused var error`

/* @type {typeof ITest} */
var x = {};
x.foo = "hello";
x.bar = 3;
// if I do `x.` intellisense should suggest `foo` and `bar` 

我想知道是否有更好的方法来解决这个问题,最好是不会引发错误的方法(使用 eslint ignore line 不是解决方法)。

澄清

这个问题不是关于从打字文件中获取功能。它纯粹是关于使 VSCode 智能感知与类型接口一起工作。这是一张图片来解释我想要的是什么(圆圈内的两条线):

我认为您的问题可能存在概念上的误解。听起来您希望接口在运行时 可用。 Typescript 接口纯粹是一个编译时概念。他们不编译任何东西。它们在运行时不存在。

我把你的这部分代码放在一个名为 interf.d.ts:

的文件中
export namespace Interfaces {
    export interface Interface {
        property: string;
    }
}

然后我创建了文件 test.ts:

import { Interfaces } from "./interf";

const x: Interfaces.Interface = {
    property: "abc",
};

console.log(x);

我没有遇到编译错误,而且执行得很好。正如预期的那样,接口 导出。您稍后导出的 const 不需要导出接口(无论如何它 不是 导出接口,它导出一个 const声明符合接口,但const不是接口)。

但是,如果您试图在已编译的 JavaScript 中找到与您的界面相对应的内容,您将找不到它,原因我在上面给出:它是一个编译时构造.

所以我能够使用 JSDoc 解决问题

test.d.ts

export namespace test {
    export interface ITest {
        foo: string;
        bar: number;
    }
}

test.js

/**
 * @type {import("./test").test.ITest}
 */

let x;

x.

智能感知现在可用

另外一件事我发现如果你添加 jsconfig.json

jsconfig.json

{
    "compilerOptions": {
        "checkJs": true
    }
}

你的智能感知得到进一步提升

Update-1

正如@nickzoum 所指出的,如果您像下面这样定义 test.d.ts

export interface ITest {
    foo: string;
    bar: number;
}

export as namespace test;

那你也可以在JS中使用下面的形式进行intellisense

/** @typedef {import("./test").ITest} ITest */

/** @type {ITest} */
var x = {};
x.

我发现了一些不需要任何额外配置且使用简单的东西,但你需要配置一个 tsconfig.json。

tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "moduleResolution": "node",
    "baseUrl": "../",
    "noEmit": true,
    "target": "es5"
  }
}

test.d.ts

export = Test
export as namespace Test
declare namespace Test {
  interface ITest {
    foo: string;
    bar: number;
  }
}

test.js

/**
 * @type {Test.ITest}
 */
let x;