I am curious about .d.ts declaration files because I am new to the TypeScript programming language. I was told by someone that .d.ts files are are similar to .h header files in the C & C++ programming languages, however, the .d.ts files don't seem to work quite the same. Currently, I am failing to understand how to properly use the .d.ts files. It would appear that I cant add my .js or .ts files to the .d.ts files, so the only way my project will work is if it contains all three file types. That seems like a lot of files. To help me better understand how the .d.ts files are related to JavaScript & TypeScript, I have some questions I would like to ask.


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


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


当前回答

如@takeshin所说,.d代表typescript (.ts)的声明文件。

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

Typescript是javascript的语法超集。 Typescript不会自己运行,它需要转换成javascript (Typescript到javascript的转换) “类型定义”和“类型检查”是typescript在javascript上提供的主要附加功能。(检查script和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

并尝试在typescript代码中导入它

import * from "mylib";

你会得到错误。

"找不到'mylib'模块。"

正如@Chris提到的,很多库,如underscore, Jquery已经用javascript编写了。与其为typescript项目重新编写这些库,还需要另一种解决方案。

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

现在当你试着

import * from "mylib";

Mylib.d.ts被导入,作为javascript库代码和typescript项目之间的接口。

其他回答

d代表Declaration Files:

When a TypeScript script gets compiled there is an option to generate a declaration file (with the extension .d.ts) that functions as an interface to the components in the compiled JavaScript. In the process the compiler strips away all function and method bodies and preserves only the signatures of the types that are exported. The resulting declaration file can then be used to describe the exported virtual TypeScript types of a JavaScript library or module when a third-party developer consumes it from TypeScript. The concept of declaration files is analogous to the concept of header file found in 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中 注册表。提供了一个名为typings的命令行实用程序来提供帮助 从存储库中搜索并安装声明文件。

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

使用。d。ts文件映射JavaScript需要你命名你的。d。Ts文件与你命名的.js文件相同。每个.js文件需要与.d. js文件保持内联(保持在同一个目录中)。Ts文件,具有相同的名称。指向需要.d中的类型的JS/TS代码。Ts文件到。d。ts文件。

例如:test.js和test.d.ts在testdir/文件夹中,然后你像这样在react组件中导入它:

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

.d。Ts文件被导出为如下的命名空间:

export as namespace Test;
    
export interface TestInterface1{}
export class TestClass1{}

因为源代码是真相的最终来源。这里似乎是它的实现:

/*
 * Every module resolution kind can has its specific understanding how to load module from a specific path on disk
 * I.e. for path '/a/b/c':
 * - Node loader will first to try to check if '/a/b/c' points to a file with some supported extension and if this fails
 * it will try to load module from directory: directory '/a/b/c' should exist and it should have either 'package.json' with
 * 'typings' entry or file 'index' with some supported extension
 * - Classic loader will only try to interpret '/a/b/c' as file.
 */
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;

and

/**
 * Kinds of file that we are currently looking for.
 */
const enum Extensions {
    TypeScript  = 1 << 0, // '.ts', '.tsx', '.mts', '.cts'
    JavaScript  = 1 << 1, // '.js', '.jsx', '.mjs', '.cjs'
    Declaration = 1 << 2, // '.d.ts', etc.
    Json        = 1 << 3, // '.json'

    ImplementationFiles = TypeScript | JavaScript,
}

完整的文件是https://github.com/microsoft/TypeScript/blob/main/src/compiler/moduleNameResolver.ts。

这个答案假设你有一些JavaScript,你不想转换成TypeScript,但你想从类型检查中获益,对.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.s ts定义了一个接口,mashString.js实现了这个接口,main.js使用了这个接口。

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

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

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

“d.ts”文件用于提供关于用JavaScript编写的API的typescript类型信息。这个想法是你使用jQuery或下划线之类的东西,一个现有的javascript库。你想从你的typescript代码中使用它们。

而不是重写jquery或下划线或typescript中的任何东西,你可以写d.ts文件,它只包含类型注释。然后,从你的typescript代码中,你可以获得静态类型检查的typescript好处,同时仍然使用纯JS库。

这多亏了TypeScript的约束,不允许你添加“。导入语句末尾的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