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文件映射到自己?
如果有人能给我举个例子就太好了。
“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
因为源代码是真相的最终来源。这里似乎是它的实现:
/*
* 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。
如@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项目之间的接口。