【问题标题】:About "*.d.ts" in TypeScript关于 TypeScript 中的“*.d.ts”
【发布时间】:2014-02-10 09:45:26
【问题描述】:

我对 *.d.ts 感到好奇,因为我是 TypeScript 的新手。有人告诉我,这种文件类似于 C++ 中的“头文件”,但仅适用于 JS。但我无法将纯 JS 文件转换为 *.d.ts 文件,除非我强制将 *.js 更改为 *.ts。所以我有三个文件: 一个JS文件,一个TS文件和一个*.d.ts文件。


  1. 它们之间是什么关系?

  2. 如何使用*.d.ts 文件?这是否意味着我可以永久删除*.ts 文件?

  3. 如果是,*.d.ts文件怎么知道哪个JS文件映射到自己?


如果有人能举个例子就好了。

【问题讨论】:

标签: typescript .d.ts


【解决方案1】:

“d.ts”文件用于提供有关以 JavaScript 编写的 API 的 typescript 类型信息。这个想法是你正在使用 jQuery 或 underscore 之类的东西,一个现有的 javascript 库。你想从你的打字稿代码中使用那些。

您可以编写仅包含类型注释的 d.ts 文件,而不是重写 jquery 或下划线或打字稿中的任何内容。然后从您的 typescript 代码中,您可以获得静态类型检查的 typescript 优势,同时仍然使用纯 JS 库。

这要归功于 TypeScript 的限制,即不允许您在 import 语句的末尾添加“.ts”扩展名。因此,当您引用某个文件时,比如说my-module.js,如果它旁边有一个my-module.d.ts,那么TypeScript 将包含它的内容:

src/
  my-module.js
  my-module.d.ts
  index.ts

my-module.js

const thing = 42;

module.exports = { thing };

my-module.d.ts

export declare const thing: number;

index.ts

import { thing } from "./my-module"; // <- no extension

// runtime implementation of `thing` is taken from ".js"
console.log(thing); // 42

// type declaration of `thing` is taken from ".d.ts"
type TypeOfThing = typeof thing; // number

【讨论】:

  • 非常感谢!但是如何将 *.d.ts 文件映射到 js 文件呢? js文件怎么知道哪个d.ts文件映射到自己呢?可以举个例子吗?
  • 但是d.ts文件是从js文件生成的,如果js文件对d.ts一无所知。如何在没有js文件的情况下调用其他ts文件中d.ts中的函数?我很疑惑……
  • stackoverflow.com/questions/18091724/…。您需要在消费 ts 文件的顶部添加一个 ///
  • d.ts 文件一般是从 js 文件文档中手写的。其中大量可用于流行的 javascript 库:github.com/borisyankov/DefinitelyTyped
  • 如果您正在为您的项目制作自定义文件,您会将自定义 d.ts 文件放在哪里?
【解决方案2】:

d 代表Declaration Files

编译 TypeScript 脚本时,可以选择生成 一个声明文件(扩展名为 .d.ts),用作 与已编译 JavaScript 中的组件的接口。正在进行中 编译器剥离所有函数和方法体并保留 仅导出类型的签名。所结果的 然后可以使用声明文件来描述导出的虚拟 第三方 JavaScript 库或模块的 TypeScript 类型 开发人员从 TypeScript 中使用它。

声明文件的概念类似于标头的概念 在 C/C++ 中找到的文件。

declare module arithmetics {
    add(left: number, right: number): number;
    subtract(left: number, right: number): number;
    multiply(left: number, right: number): number;
    divide(left: number, right: number): number;
}

可以为现有的 JavaScript 手动编写类型声明文件 库,就像对 jQuery 和 Node.js 所做的那样。

流行 JavaScript 的大量声明文件 库托管在 GitHub 上的 DefinitelyTypedTypings Registry。提供了一个名为 typings 的命令行实用程序来提供帮助 从存储库中搜索并安装声明文件。

【讨论】:

  • 注意:typings 命令行工具从 TypeScript 2.0 开始就不再需要了。最新的方法是通过 @types 命名空间下的 npm 存储库使用类型包装器。有关详细信息,请参阅github.com/typings/typings/blob/master/README.md
  • @takeshin 我有个问题。我是否需要生成仅在我的项目内部使用的 .tsx 文件的 .d.ts 文件?除了提供可能的第 3 方库附加信息之外,这些是否还添加了其他内容?
【解决方案3】:

我无法发表评论,因此将其添加为答案。
我们在尝试将现有类型映射到 javascript 库时遇到了一些麻烦。

要将.d.ts 文件映射到其javascript 文件,您需要为.d.ts 文件提供与javascript 文件相同的名称,将它们保存在同一文件夹中,并将需要它的代码指向.d.ts文件。

例如:test.jstest.d.tstestdir/ 文件夹中,然后您将它像这样导入到 react 组件中:

import * as Test from "./testdir/test";

.d.ts 文件被导出为如下命名空间:

export as namespace Test;

export interface TestInterface1{}
export class TestClass1{}

【讨论】:

  • 没有人回答如何将d.ts连接到js,所以我认为这是正确的地方。
  • 请注意,如果您正在为某些未创建的 JS 创建声明文件(例如来自 npm 的包),则 .d.ts 文件也必须与包命名相同被导入。
  • 如果模块是这样导入的怎么办(不要问我为什么?):import x from "x/x.js" 即末尾有文件扩展名?尝试将 d.ts 文件命名为 x.js.d.ts,但这似乎不起作用
  • 文件 *.d.ts 必须是“同名”并且与 *.js 是“同一个文件夹”。我觉得上面的答案是对的
【解决方案4】:

就像@takeshin 说的 .d 代表 typescript (.ts) 的声明文件。

在继续回答这篇文章之前需要澄清几点 -

  1. Typescript 是 javascript 的语法超集。
  2. Typescript 不能自己运行,需要转译成 javascript (typescript to javascript conversion)
  3. “类型定义”和“类型检查”是 typescript 通过 javascript 提供的主要附加功能。 (check difference between type script and javascript)

如果你认为 typescript 只是句法超集,它有什么好处 - https://basarat.gitbooks.io/typescript/docs/why-typescript.html#the-typescript-type-system

回答这个帖子 -

正如我们所讨论的,typescript 是 javascript 的超集,需要被转译成 javascript。因此,如果一个库或第三方代码是用 typescript 编写的,它最终会被转换为 javascript 项目可以使用的 javascript,反之亦然。

前 -

如果你安装了 javascript 库 -

npm install --save mylib

并尝试在打字稿代码中导入它 -

import * from "mylib";

你会得到错误。

“找不到模块'mylib'。”

正如@Chris 所提到的,下划线、Jquery 等许多库已经用 javascript 编写。与其为 typescript 项目重写这些库,不如使用替代解决方案。

为了做到这一点,您可以在名为 *.d.ts 的 javascript 库中提供类型声明文件,例如上面的 mylib.d.ts。声明文件只提供各自javascript文件中定义的函数和变量的类型声明。

现在当你尝试 -

import * from "mylib";

mylib.d.ts 被导入,充当 javascript 库代码和 typescript 项目之间的接口。

【讨论】:

  • 你把 mylib.d.ts 放在哪里?它可以在您的代码库中的任何位置吗?只在顶级?是否需要一些配置文件指向它?
【解决方案5】:

工作示例用于特定案例

假设您有通过 npm 共享的 my-module

你用npm install my-module安装它

你这样使用它:

import * as lol from 'my-module';

const a = lol('abc', 'def');

模块的逻辑都在index.js:

module.exports = function(firstString, secondString) {

  // your code

  return result
}

要添加类型,请创建一个文件index.d.ts

declare module 'my-module' {
  export default function anyName(arg1: string, arg2: string): MyResponse;
}

interface MyResponse {
  something: number;
  anything: number;
}

【讨论】:

    【解决方案6】:

    此答案假定您有一些不想转换为 TypeScript 的 JavaScript,但您希望通过对 .js 的最小更改来从类型检查中受益。 .d.ts 文件非常类似于 C 或 C++ 头文件。它的目的是定义一个接口。这是一个例子:

    mashString.d.ts

    /** Makes a string harder to read. */
    declare function mashString(
        /** The string to obscure */
        str: string
    ):string;
    export = mashString;
    

    mashString.js

    // @ts-check
    /** @type {import("./mashString")} */
    module.exports = (str) => [...str].reverse().join("");
    

    main.js

    // @ts-check
    const mashString = require("./mashString");
    console.log(mashString("12345"));
    

    这里的关系是:mashString.d.ts定义接口,mashString.js实现接口,main.js使用接口。

    要使类型检查正常工作,请将// @ts-check 添加到您的.js 文件中。 但这只会检查main.js 是否正确使用了接口。为了确保mashString.js 正确实现它,我们在导出之前添加/** @type {import("./mashString")} */

    您可以使用tsc -allowJs main.js -d 创建初始.d.ts 文件,然后根据需要手动编辑它们以改进类型检查和文档。

    在大多数情况下,实现和接口具有相同的名称,此处为mashString。但是你可以有其他的实现。例如,我们可以将 mashString.js 重命名为 reverse.js 并有一个替代的 encryptString.js

    【讨论】:

      【解决方案7】:

      我想我可以在这里加我的 2 美分

      // somefile.d.ts
      export type SomeItem = {
        weight: number
      }
      
      export type ItemStorage = {
        name: string
        items: SomeItem[]
      }
      
      // simefile.js
      // @ts-check
      /** @typedef { import('./somefile.d.ts').SomeItem } SomeItem */
      /** @typedef { import('./somefile.d.ts').ItemStorage } ItemStorage */
      
      /**
       * @param { StorageItem } item
       */
      function doSomething(item) {
        item. // intellisense
        // your code here
      }
      

      这样做的好处是可以逐渐将类型合并到现有的 javascript 项目中。

      【讨论】:

        【解决方案8】:

        例如,您在使用 npm 中的“alertifyjs”模块时遇到了问题。

        1. 创建“anyNameYoulike.d.ts”(例如,您在 src 文件夹中创建了此文件)
        2. 在文件中 声明模块“alertifyjs”; enter image description here
        3. 在 tsconfig.json 中 在“编译器选项”下 "typeRoots": ["node_modules/@types", "src/anyNameYoulike.d.ts"]

        【讨论】:

        • 请将此作为评论重新发布。
        • @Yserbius 这个答案的长度怎么可能是评论?
        猜你喜欢
        • 2016-05-07
        • 1970-01-01
        • 2015-09-11
        • 1970-01-01
        • 2019-10-22
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多