1

TypeScript tsc -d "declaration" of "compilerOptions" generates corresponding '.d.ts' file.

For instance, from:

tmp.ts

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

it generates:

tmp.js

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

and:

tmp.d.ts

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

I think this is quite interesting because it "devides" the TypeScript source code to a native JavaScript code and the extra type definition.

Then, here is my thought. After deviding the native code and type definition, is it easily possilbe to generate a valid TypeScript code by re-binding both codes.

For instance:

tmp-reunion.ts

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

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

This code generates an errors:

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

for each statements.

Why am I doing this?

I'm motivated by facts:

  1. In Algebra,

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

I want to confirm if the same thing is valid under TypeScript.

  1. It's especially interesting TypeScript compiles a typed-source-code to a vanilla JavaScript code having the type information completely discarded as the output.

The fact makes me think, in a sense, the output of the vanilla JS code is type safe and valid with TypeScirpt, just without the *.d.ts file which is eventually appearently merely an extra helper functionality that TypeScript compiler takes advantage of. It's just a tool.

Accordingly, the type-safty of the vanilla JS code can be later, easily validated by TypeScript compiler with the helper functional tool, that is tmp.d.ts. That is what I want to confirm.

How can I make TypeScript combining *.js + *.d.ts again?

Thanks.

5
  • The algebraic motivation is very vague. What is the algebraic structure here which you want to prove to be distributive? Otherwise it just sounds like "a+b = b+a, so why does order matter anywhere in the universe". Apples and oranges. Commented Jul 31, 2018 at 5:21
  • @IngoBürk It's not about commutative law, but about factorization and restoration. I thought I made it clear. I use i3, by the way. Commented Jul 31, 2018 at 5:32
  • I don't see how "factorization and restoration" in Algebra is at all relevant for this, though. There's plenty of processes in the world that aren't reversible. Commented Jul 31, 2018 at 5:50
  • @IngoBürk Yeah, I know. That's the point. In other words, is it reversible or irreversible? You certainly got the point. That's the problem. In math, the factorization is reversible, and differential is irreversible. Commented Jul 31, 2018 at 5:59
  • Alright, gotcha. Commented Jul 31, 2018 at 6:24

1 Answer 1

3

Accordingly, the type-safty of the vanilla JS code can be later, easily validated by TypeScript compiler with the helper functional tool, that is tmp.d.ts.

This is not true in general because you've lost any manual type annotations inside function bodies that were needed to validate those function bodies where TypeScript's type inference was insufficiently powerful. For an artificial example (assuming noImplicitAny of course):

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

If you remove the annotation on out, the code doesn't compile because TypeScript's evolving array type inference doesn't traverse into callbacks. If we look at the .d.ts and the .js, this annotation doesn't appear in either of them:

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

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

For more realistic examples, look at any nontrivial TypeScript codebase.

Sign up to request clarification or add additional context in comments.

12 Comments

Thanks. In other my code, the *.d.ts is declare const isType: (I: Function) => (i: unknown) => boolean | ((i: { [key: string]: object; }) => boolean); and I thought *.d.ts doesn't lose any infromation. I don't know where to see to check the behavior the tsc -d have lost type information in *.d.ts. Can you show me where? Thanks again.
In that particular example, nothing may have been lost. I added an example in which information is lost to my answer.
Thanks again, I must search more complicated scenario. I'm sorry if I miss your point, but looking at your example I feel : T[]; in *.d.ts corresponds to var out = []; return out; in the source.
Do you mean you think the compiler should infer that var out is of type T[] because it is being returned and the function's return type is given as T[] in the .d.ts? Currently it doesn't. You could imagine enhancing the inference that way, but doing so might have other undesired effects and there will always be some more complicated scenario the inference can't handle.
Actually, I am not questioning the inferring ability of the compiler, and what I am asking is if it is true in *.d.ts file, the TypeScript compiler could omit a certain information to pass the validation at compile.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.