Skip to content

Error when trying to emit declarations for a module with a non exported base class #9865

Closed

Description

TypeScript Version: 2.0.0

Code

// file: animal.ts
abstract class Animal {
    name: string;

    constructor(name: string) {
      this.name = name;
    }

    abstract shout(): string;
}

export class Snail extends Animal {
    shout(): string {
        return '...';
    }
}

I'm trying to emit declarations files .d.ts with tsc --declaration in order to get such a following file:

Expected behavior:
File animal.js well generated as well as file animal.d.ts:

// file: animal.d.ts
declare abstract class Animal {
    name: string;
    constructor(name: string);
    abstract shout();
}

export declare class Snail extends Animal {
    shout();
}

Actual behavior:
File animal.js well generated but no file animal.d.ts. I got an error instead:
error TS4020: Extends clause of exported class 'Snail' has or is using private name 'Animal'.

It is maybe a misunderstanding of mine, but in my mind, when a code compiles with tsc, it should also compile with the --declaration flag.

For information, here is my tsconfig.json:

// file: tsconfig.json
{
    "compilerOptions": {
        "noImplicitAny": true,
        "strictNullChecks": true,
        "target": "es5",
        "module": "amd",
        "outDir": "./build"
    },
    "exclude" : [
        "./build",
        "./node_modules"
    ]
}

Activity

  1. mhegazy commented on Jul 21, 2016

    @mhegazy
    Contributor

    It is maybe a misunderstanding of mine, but in my mind, when a code compiles with tsc, it should also compile with the --declaration flag.

    Generating a declaration file requires some additional restricts, e.g. that the types used in an exported declaration have the same visibility. these errors are not reported if you do not care about declaration files.

    in this sample you need to export your abstract class as well.

  2. yahiko00 commented on Jul 22, 2016

    @yahiko00
    Author

    I can understand the restriction you mention although it means we always have to export a whole type hierarchy, from top to bottom. But why not.

    However, what is quite disturbing, is when such a definition file above, animal.d.ts (without export on the base class), is consumed by TypeScript, it compiles perfectly well. No error nor warning.

    From my point of view, this restriction when emitting should be removed, since it compiles (emission and consumption), or tsc without --declaration flag should report an error as well (when emitting and consuming).

  3. mhegazy commented on Jul 22, 2016

    @mhegazy
    Contributor

    However, what is quite disturbing, is when such a definition file above, animal.d.ts (without export on the base class), is consumed by TypeScript, it compiles perfectly well. No error nor warning.

    emitting declarations adds additional restrictions that are not needed if you are not emitting declarations.

    From my point of view, this restriction when emitting should be removed,

    the rational here is in a .d.ts file all declarations are exported by default regardless of the export keyword. so

    declare abstract class Animal {
     ....
    }
    export declare class Snail extends Animal {
     ....
    }

    really exports two classes, Animal and Snail.

    so the error, in a sense, tells you this is going to happen. you can then decide if this is what you really intend, or you want change the public shape of Snail to be what you expect.

  4. yahiko00 commented on Jul 22, 2016

    @yahiko00
    Author

    Ok, I resign ^^. Good to know --declaration flag adds addition checks. I may use it for pedantic compilation.

  5. mhegazy commented on Jul 22, 2016

    @mhegazy
    Contributor

    One thing to note, the errors you get from declaration emit are only "visibility" errors. so no new type relationship constraints, or syntax checks. it is just something of two forms:

    • "A uses B, and B is not exported"
    • "A" is used but the compiler could not write its name (either shadowed by something with the same name, or comes from a different module that was not imported)
  6. yahiko00 commented on Jul 22, 2016

    @yahiko00
    Author

    Maybe the compiler could be nice to generate the corresponding .d.ts file although complaining :p

  7. mhegazy commented on Jul 23, 2016

    @mhegazy
    Contributor

    that is possible. the reason here is, some other part of your system might be using the declaration file to build against or get intellisense, and overriding an existing declaration file with one that is known to have errors did not seem like the right experience.

  8. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions