在 typings 文件中声明 JavaScript 接口

12

项目信息

我正在开发一个使用.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智能提示与类型接口一起工作。下面的图片解释了我想要的内容(圆圈内的两行代码):

进入图片描述

3个回答

14

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

test.d.ts

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

test.js

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

let x;

x.

现在智能感知功能已经运行。

Working intellisense

另外我发现一个事情,如果你添加了 jsconfig.json 并且

jsconfig.json

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

你的智能感知进一步提升了。

更好的智能感知

更新-1

正如@nickzoum所指出的,如果您定义test.d.ts如下:

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

export as namespace test;

然后你还可以在JS中使用以下格式来获得智能提示

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

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

似乎你仍然可以将声明包装在你想要的命名空间中。但是你还必须在全局范围内使用 export namespace as randomName。因此,如果你只是在第一个示例中添加了 export namespace as randomName,那么你就可以执行 @typedef {import("./test")} JSDoc,然后 /** @type {JSDoc.test.ITest} */ - nick zoum

6

我认为你遇到的问题可能存在一个概念上的误解。听起来你想要在运行时使用接口。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中找到与你的接口相对应的内容,由于上述原因,你找不到它:它是一个编译时的结构。

3
我发现一个简单易用且不需要任何额外配置就能工作的东西,但你需要配置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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接