GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — type `nothing` emitted in generated .d.ts files · Issue #8345 · microsoft/TypeScript

type nothing emitted in generated .d.ts files #8345

New issue
Copy link
New issue
Copy link
Closed
Closed
type nothing emitted in generated .d.ts files#8345
Copy link
Assignees
ahejlsberg
Labels
BugA bug in TypeScriptA bug in TypeScriptFixedA PR has been merged for this issueA PR has been merged for this issue
Milestone
TypeScript 2.0

Description

@mhegazy
Mohamed Hegazy (mhegazy)
opened on Apr 28, 2016
Issue body actions
function f() {
    var x: string | undefined = undefined;
    y = 0;
    if (x) {
       var y: typeof x;
    }
    return y; // y has type nothing
}

generates invalid .d.ts file

declare function f(): nothing;

this is a regression introduced by #8340

Activity

  1. Mohamed Hegazy (mhegazy)
    added
    BugA bug in TypeScriptA bug in TypeScript
    on Apr 28, 2016
  2. ahejlsberg commented on Apr 28, 2016

    @ahejlsberg
    Anders Hejlsberg (ahejlsberg)
    on Apr 28, 2016
    Member
    More actions

    I'm tempted to say just don't do that. But I won't. 😉

    I definitely don't think the solution is to make nothing a manifest type that you can reference in a type annotation. That leaves rewriting (but to what?) or issuing an error. The error is probably the better option.

  3. DanielRosenwasser commented on Apr 28, 2016

    @DanielRosenwasser
    Daniel Rosenwasser (DanielRosenwasser)
    on Apr 28, 2016
    Member
    More actions

    I get why {} was not appropriate. But nothing sounds a heck of a lot like what I'd associate void with, so what exactly is the intended difference semantically?

  4. mihailik commented on Apr 28, 2016

    @mihailik
    mihailik
    on Apr 28, 2016
    Contributor
    More actions

    Can it return any and for those interested in picking at those little tiny details let noImplicitAny generate an error?

  5. ahejlsberg commented on Apr 28, 2016

    @ahejlsberg
    Anders Hejlsberg (ahejlsberg)
    on Apr 28, 2016
    Member
    More actions

    Daniel Rosenwasser (@DanielRosenwasser) There are a couple of important differences between void and nothing.

    • The undefined type is assignable to void, but no types are assignable to nothing.
    • void can be a constituent of a union type, but nothing disappears in a union type (because it signifies no type at all).

    I do agree we have bit of a profusion of nothingness types (undefined, null, void, nothing), but they all have important differences. If anything had to change, we could possibly consider removing the undefined type and having void be the type of the undefined literal. But that would allow silly stuff like assigning the result of a void function to a variable can be undefined, which really should be an error.

  6. mhegazy commented on Apr 28, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on Apr 28, 2016
    ContributorAuthor
    More actions

    here is a less artificial example:

    function bar() {
        var x: string | undefined;
        if (x) {
            return x;
        }
        throw new Error();
    }
  7. mhegazy commented on Apr 28, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on Apr 28, 2016
    ContributorAuthor
    More actions

    so for .d.ts purposes, should we 1. write void, 2. undefined, 3. nothing and make it legal to name this type.

  8. ahejlsberg commented on Apr 28, 2016

    @ahejlsberg
    Anders Hejlsberg (ahejlsberg)
    on Apr 28, 2016
    Member
    More actions

    (1) and (2) aren't correct and (3) really doesn't help anyone. I think we should (4) issue an error.

  9. ahejlsberg commented on Apr 28, 2016

    @ahejlsberg
    Anders Hejlsberg (ahejlsberg)
    on Apr 28, 2016
    Member
    More actions

    Adding some rationale for (4): There's really no situation ever where you want nothing to be the declared type of an entity. It is typically an indicator of a logic error, but we don't want to eagerly issue the error because you may be writing "defensive" code that deals with incorrect parameters passed from code that doesn't follow the stated contract (such as plain JavaScript).

  10. mihailik commented on Apr 28, 2016

    @mihailik
    mihailik
    on Apr 28, 2016
    Contributor
    More actions
    function bar() {
        throw new Error();
    }

    Under these reasoning this should produce error too.

  11. mhegazy commented on Apr 28, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on Apr 28, 2016
    ContributorAuthor
    More actions

    no that is void.

  12. mihailik commented on Apr 28, 2016

    @mihailik
    mihailik
    on Apr 28, 2016
    Contributor
    More actions

    Exactly, and that's the same code as in your example (sans no-op if).

    Do we end-users of the compiler need this level of precision? By all means it may add value internally, but best reduce peculiarity on the outside, coercing nothing to void or unknown in codegen/diagnostic messages.

  13. mhegazy commented on Apr 28, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on Apr 28, 2016
    ContributorAuthor
    More actions

    void means it returns no value. nothing means it returned a value, but its type was narrowed down by the compiler to nothing. The assumption is that is never the intention of the user. so if you did not mean for this to happen, so you might want to take a look at the source and see where did the nothing came from, and the error does that.

  14. aluanhaddad commented on Apr 28, 2016

    @aluanhaddad
    Aluan Haddad (aluanhaddad)
    on Apr 28, 2016
    Contributor
    More actions

    Do we end-users of the compiler need this level of precision? By all means it may add value internally, but best reduce peculiarity on the outside, coercing nothing to void or unknown in codegen/diagnostic messages.

    The TypeScript compiler is a TypeScript program so I do not think that would be either possible or valuable.

    👍 for making it an error.

  15. mihailik commented on Apr 29, 2016

    @mihailik
    mihailik
    on Apr 29, 2016
    Contributor
    More actions

    Mohamed Hegazy (@mhegazy) unless this detection generates false positives, as Anders Hejlsberg (@ahejlsberg) pointed out above.

    function validateType(val: number | string) {
        if (typeof val === 'string') return null;
        else {
            if (typeof val === 'number') return null;
            else return val; // validation fails at runtime, but this code is valid
        }
    }
    
    function validateTypeMoreDetails(val: number | string) {
        if (typeof val === 'string') return null;
        else {
            if (typeof val === 'number') return null;
            else return 'Incorrect type ' + typeof val+' ('+val+')'; // should 'nothing' support plus operator with string?
        }
    }
  16. mihailik commented on Apr 29, 2016

    @mihailik
    mihailik
    on Apr 29, 2016
    Contributor
    More actions

    Set theory (empowered by union and intersection types) is bound to produce oddities -- hence a need to limit that power in places where it becomes too exotic and impractical.

    Coercing nothing to void or similar may be one of those intentional trivializations for the sake of sanity and practicality. You know saying 'the buck stops with me'? Make that nothing buck stay within the compiler, don't pass it out in the world.

  17. DanielRosenwasser commented on Apr 29, 2016

    @DanielRosenwasser
    Daniel Rosenwasser (DanielRosenwasser)
    on Apr 29, 2016
    Member
    More actions

    I don't think the nothing type is actually that big of a deal, I just think it's odd to make it an inexpressible type. I don't see a reason to limit users from writing it out like with how null and undefined use to be disallowed.

  18. jeffreymorlan commented on Apr 29, 2016

    @jeffreymorlan
    jeffreymorlan
    on Apr 29, 2016
    Contributor
    More actions

    There's really no situation ever where you want nothing to be the declared type of an entity.

    A function that always throws an exception, never returning normally, logically has a return value of nothing. Unlike a void-returning function, a nothing-returning function could safely be assigned to any other return type:

    function stub() { throw Error("Unimplemented"); }
    interface SomeInterface {
        someMethod(): number;
        someIrrelevantMethod1(): number;
        someIrrelevantMethod2(): string;
    }
    var obj: SomeInterface = {
        someMethod() { ... },
        someIrrelevantMethod1: stub,
        someIrrelevantMethod2: stub
    };

    Currently this is an error, despite being perfectly type-safe - making stub return nothing would fix that. (Or any, but that makes the type less self-documenting)

  19. aluanhaddad commented on Apr 29, 2016

    @aluanhaddad
    Aluan Haddad (aluanhaddad)
    on Apr 29, 2016
    Contributor
    More actions

    jeffreymorlan perfectly typesafe, but known to produce an error when invoked.

  20. mhegazy commented on May 17, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on May 17, 2016
    ContributorAuthor
    More actions

    should be fixed by #8652

  21. Mohamed Hegazy (mhegazy)
    assigned
    ghost
    and
    Anders Hejlsberg (ahejlsberg)
    and unassigned on May 17, 2016
  22. Mohamed Hegazy (mhegazy)
    added this to the TypeScript 2.0 milestone on May 17, 2016
  23. ahejlsberg commented on May 18, 2016

    @ahejlsberg
    Anders Hejlsberg (ahejlsberg)
    on May 18, 2016
    Member
    More actions

    Fixed in #8652.

  24. Anders Hejlsberg (ahejlsberg)
    closed this as completedon May 18, 2016
  25. Mohamed Hegazy (mhegazy)
    added
    FixedA PR has been merged for this issueA PR has been merged for this issue
    on May 18, 2016
  26. microsoft
    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

  • @ahejlsberg
    Anders Hejlsberg (ahejlsberg)

Labels

BugA bug in TypeScriptA bug in TypeScriptFixedA PR has been merged for this issueA PR has been merged for this issue

Type

No type

Projects

No projects

    Milestone

    • TypeScript 2.0

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.