【问题标题】:TypeScript combining *.js + *.d.ts again?TypeScript 再次结合 *.js + *.d.ts?
【发布时间】:2018-07-31 04:10:19
【问题描述】:

TypeScript tsc -d "compilerOptions" 的 "declaration" 生成相应的 '.d.ts' 文件。

例如,来自:

tmp.ts

const log = (m: unknown) => {
    console.log((m)); 
    return m;
};

它生成:

tmp.js

const log = (m) => {
    console.log((m));
    return m;
};

和:

tmp.d.ts

declare const log: (m: unknown) => unknown;

我认为这很有趣,因为它将 TypeScript 源代码“划分”为原生 JavaScript 代码和额外的类型定义。

那么,这是我的想法。将原生代码和类型定义分开后,是否可以通过重新绑定这两个代码轻松生成有效的 TypeScript 代码。

例如:

tmp-reunion.ts

declare const log1: (m: unknown) => unknown;

const log1 = m => {
    console.log((m)); 
    return m;
};

此代码生成错误:

[ts] Cannot redeclare block-scoped variable 'log1'.

对于每个语句。

我为什么要这样做?

我的动机是事实:

  1. 在代数中,

    (x^2 + 3x +2) = (x+1)(x+2) = (x^2 + 3x +2)

我想确认同样的东西在 TypeScript 下是否有效。

  1. 特别有趣的是,TypeScript 将类型化源代码编译为普通 JavaScript 代码,其中类型信息完全丢弃作为输出。

事实让我认为,从某种意义上说,原始 JS 代码的输出是类型安全的,并且对 TypeScirpt 有效,只是没有 *.d.ts 文件,该文件最终似乎只是 TypeScript 编译器采用的额外帮助功能的优势。它只是一个工具。

因此,原版 JS 代码的类型安全性可以稍后通过 TypeScript 编译器使用辅助功能工具 (tmp.d.ts) 轻松验证。这是我想确认的。

我该怎么做 TypeScript 再次结合 *.js + *.d.ts?

谢谢。

【问题讨论】:

  • 代数动机非常模糊。这里你想证明它是可分配的代数结构是什么?否则,它听起来就像“a+b = b+a,那么为什么秩序在宇宙中的任何地方都很重要”。苹果和橙子。
  • @IngoBürk 这不是关于交换律,而是关于分解和恢复。我以为我说清楚了。顺便说一句,我用的是 i3。
  • 我不明白代数中的“分解和恢复”与此有什么关系。世界上有很多过程是不可逆的。
  • @IngoBürk 是的,我知道。这才是重点。换句话说,它是可逆的还是不可逆的?你当然明白了。那就是问题所在。在数学中,因式分解是可逆的,而微分是不可逆的。
  • 好吧,明白了。

标签: javascript typescript types


【解决方案1】:

因此,vanilla JS 代码的类型安全性可以稍后通过 TypeScript 编译器使用辅助功能工具(即tmp.d.ts)轻松验证。

这通常是不正确的,因为您在函数体中丢失了任何手动类型注释,这些注释是验证那些 TypeScript 类型推断功能不够强大的函数体所需的。举一个人为的例子(当然假设noImplicitAny):

function duplicateEach<T>(arr: T[]) { 
    let out: T[] = [];
    arr.forEach(t => { out.push(t); out.push(t); });
    return out;
}

如果您删除 out 上的注释,则代码不会编译,因为 TypeScript 不断发展的数组类型推断不会遍历回调。如果我们查看.d.ts.js,这两个注释都不会出现:

declare function duplicateEach<T>(arr: T[]): T[];

function duplicateEach(arr) {
    var out = [];
    arr.forEach(function (t) { out.push(t); out.push(t); });
    return out;
}

有关更实际的示例,请查看任何重要的 TypeScript 代码库。

【讨论】:

  • 谢谢。在我的其他代码中,*.d.ts 是declare const isType: (I: Function) =&gt; (i: unknown) =&gt; boolean | ((i: { [key: string]: object; }) =&gt; boolean); ,我认为 *.d.ts 不会丢失任何信息。我不知道在哪里可以检查 tsc -d 在 *.d.ts 中丢失类型信息的行为。你能告诉我在哪里吗?再次感谢。
  • that particular example 中,可能没有丢失任何内容。我添加了一个示例,其中我的答案丢失了信息。
  • 再次感谢,我必须搜索更复杂的场景。如果我错过了您的观点,我很抱歉,但是看着您的示例,我觉得 *.d.ts 中的 : T[]; 对应于源中的 var out = []; return out;
  • 你的意思是你认为编译器应该推断var out 的类型是T[],因为它正在被返回并且函数的返回类型在.d.ts 中给出为T[]?目前没有。您可以想象以这种方式增强推理,但这样做可能会产生其他不良影响,并且总会有一些推理无法处理的更复杂的场景。
  • 其实我并不是在质疑编译器的推断能力,我要问的是如果在*.d.ts文件中是真的,TypeScript编译器可以省略某些信息来传递编译时验证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2019-10-22
  • 2017-04-02
  • 2018-08-20
  • 2021-02-10
相关资源
最近更新 更多