简体   繁体   English

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

[英]Declare Interfaces in typings file for JavaScript

Project Info 项目信息

I'm working on a JavaScript project that utilizes .d.ts files. 我正在使用.d.ts文件的JavaScript项目。 This is a subsequent question to a question I previously asked, so you can view more information regarding the project here . 这是我先前提出的问题的后续问题,因此您可以在此处查看有关该项目的更多信息。

Problem 问题

Although I can normally extract functions from the typings files I can't extract interfaces or namespaces that are either empty or consist purely of interfaces. 尽管我通常可以从类型文件中提取函数,但是我不能提取为空或仅由接口组成的接口或名称空间。 I have temporarily fixed this problem by creating a const implementation for each interface and using @typeof ConstantImplementation in the comments. 我已通过为每个接口创建const实现并在注释中使用@typeof ConstantImplementation来临时解决此问题。 See Example below: 请参见下面的示例:

// 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` 

I was wondering if there is a better way to go around the problem, preferably one that doesn't throw an error (using eslint ignore line isn't a fix). 我想知道是否有更好的方法来解决该问题,最好是一种不会抛出错误的方法(使用eslint ignore line不是解决方案)。

Clarification 澄清度

This question is not about getting functionality from typings file. 这个问题与从打字文件获取功能无关。 It's purely about making VSCode intellisense working with typings Interfaces. 纯粹是要使VSCode智能感知与类型接口一起使用。 Here is an image to explain what it is that I want (the two lines inside the circle): 这是一张图片,解释我想要什么(圆圈内的两行):

在此处输入图片说明

I'm thinking there may be a conceptual misunderstanding that underlies your problem here. 我认为可能存在概念上的误解,这是您在此处遇到的问题的基础。 It sounds like you want the interfaces to be available at runtime . 听起来您希望这些接口在运行时可用。 Typescript interfaces are purely a compile-time concept. Typescript接口纯粹是一个编译时概念。 They do no compile to anything. 他们不编译任何东西。 They have no existence at runtime. 它们在运行时不存在。

I took this part of your code and put it in a file named interf.d.ts : 我将您的代码的这一部分放入了一个名为interf.d.ts的文件中:

export namespace Interfaces {
    export interface Interface {
        property: string;
    }
}

Then I created the file test.ts : 然后我创建了文件test.ts

import { Interfaces } from "./interf";

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

console.log(x);

I get no compilation error, and it executes just fine. 我没有编译错误,并且执行得很好。 As expected, the interface is exported. 如预期的那样,接口导出。 The const you export later is not needed to export the interface (and anyway it does not export an interface, it exports a const which is declared to conform to the interface, but the const is not the interface). const你以后出口不需要导出接口(反正它出口的接口,它导出一个const ,其声明,以符合接口,但const 不是接口)。

However, if you're trying to find something in the compiled JavaScript that corresponds to your interface, you won't find it, for the reason I gave above: it is a compile-time construct. 但是,如果您试图在已编译的JavaScript中找到与您的接口相对应的内容,则由于我上面给出的原因,您将找不到它:它是一个编译时构造。

So I was able to solve the issue using JSDoc 所以我能够使用JSDoc解决问题

test.d.ts 测试文件

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

test.js test.js

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

let x;

x.

And the intellisense works nows 而智能感知现在

工作智能

Also one thing I found is that if you add jsconfig.json with 我发现的另一件事是,如果您添加jsconfig.json

jsconfig.json jsconfig.json

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

Your intellisense improves further 您的智商进一步提高

更好的智能感知

Update-1 更新1

As pointed out by @nickzoum, if you define the test.d.ts like below 正如@nickzoum所指出的,如果您定义test.d.ts如下

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

export as namespace test;

Then you can also use below form in JS for intellisense 然后您也可以在JS中使用以下形式进行智能感知

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

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

I found something that is working without any extra configuration and with a simple usage, but you need to configure a tsconfig.json. 我发现无需任何额外配置并且使用简单即可运行的某些东西,但是您需要配置tsconfig.json。

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 test.js

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM