ChatGPT解决这个技术问题 Extra ChatGPT

关于 TypeScript 中的“*.d.ts”

我对 .d.ts 声明文件很好奇,因为我是 TypeScript 编程语言的新手。有人告诉我,.d.ts 文件类似于 C & 中的 .h 头文件。然而,C++ 编程语言,.d.ts 文件的工作方式似乎不太一样。目前,我无法理解如何正确使用 .d.ts 文件。我似乎无法将我的 .js.ts 文件添加到 .d.ts 文件中,因此我的项目工作的唯一方法是它包含所有三种文件类型。这似乎是很多文件。为了帮助我更好地理解 .d.ts 文件是如何与 JavaScript & TypeScript,我有一些问题想问。

这三个文件有什么关系?他们之间的关系?如何使用 *.d.ts 文件?这是否意味着我可以永久删除 *.ts 文件?如果是这样,*.d.ts 文件如何知道哪个 JS 文件映射到自己?

如果有人能给我举个例子,那就太好了。

对于未来的人:查看 TypeScript 文档:typescriptlang.org/docs/handbook/declaration-files/templates/…

P
Parzh from Ukraine

“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

我的模块.js

const thing = 42;

module.exports = { thing };

我的模块.d.ts

export declare const thing: number;

索引.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 文件的顶部添加一个 ///<reference 行。您需要同时提供 d.ts 和 .js 文件。
d.ts 文件通常是从 js 文件文档中手写的。其中大量可用于流行的 javascript 库:github.com/borisyankov/DefinitelyTyped
如果您正在为您的项目制作自定义文件,您将自定义 d.ts 文件放在哪里?
i
iliketocode

d 代表 Declaration Files

编译 TypeScript 脚本时,可以选择生成声明文件(扩展名为 .d.ts),该文件用作已编译 JavaScript 中组件的接口。在此过程中,编译器会剥离所有函数和方法体,只保留导出类型的签名。然后,当第三方开发人员从 TypeScript 使用它时,生成的声明文件可用于描述 JavaScript 库或模块的导出的虚拟 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 上的definitelyTyped 和 Typings Registry 中。提供了一个名为 typings 的命令行实用程序来帮助从存储库中搜索和安装声明文件。


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

我从不得不使用 .d.ts 文件煞费苦心地映射 JavaScript 项目中学到了以下知识。

使用 .d.ts 文件映射 JavaScript 要求您将 .d.ts 文件命名为与 .js 文件命名相同。每个 .js 文件都需要与同名的 .d.ts 文件保持内联(保存在同一目录中)。将需要类型的 JS/TS 代码从 .d.ts 文件指向 .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" ie 末尾有文件扩展名怎么办?尝试命名 d.ts 文件 x.js.d.ts 但这似乎不起作用
文件 *.d.ts 必须是“同名”并且与 *.js 是“同一个文件夹”。我觉得上面的答案是对的
B
Boris Yakubchik

针对特定案例的工作示例:

假设您有通过 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;
}

M
Michal

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

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

Typescript 是 javascript 的语法超集。 Typescript 不能自行运行,它需要被转译成 javascript(typescript 到 javascript 的转换)。“类型定义”和“类型检查”是 typescript 通过 javascript 提供的主要附加功能。 (检查类型脚本和 javascript 之间的区别)

如果您正在考虑打字稿是否只是句法超集,它有什么好处 - 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 编写。与其为打字稿项目重写这些库,不如使用替代解决方案。

为了做到这一点,您可以在名为 *.d.ts 的 javascript 库中提供类型声明文件,就像上面的例子 mylib.d.ts 一样。声明文件仅提供在相应 javascript 文件中定义的函数和变量的类型声明。

现在当你尝试 -

import * from "mylib";

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


你到底把 mylib.d.ts 放在哪里?它可以在您的代码库中的任何位置吗?只在顶级?是否需要一些配置文件指向它?
J
James

此答案假定您有一些不想转换为 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


K
Kostas Minaidis

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

// somefile.d.ts
export type SomeItem = {
  weight: number
}

export type ItemStorage = {
  name: string
  items: SomeItem[]
}
// somefile.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 项目中。


C
Chan Chung

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

创建“anyNameYoulike.d.ts”(例如,您在 src 文件夹中创建了此文件)在文件中声明模块“alertifyjs”;在 tsconfig.json 中输入图像描述 在 "compilerOptions" "typeRoots": ["node_modules/@types", "src/anyNameYoulike.d.ts"]


请将此作为评论重新发布。
@Yserbius 这个答案的长度怎么可能是评论?