Skip to content

Special bottom type #3076

Closed
Closed
@Artazor

Description

@Artazor

I think that it should be special bottom type with the following properties:

  • ( T | bottom ) = ( bottom | T ) = T — bottom is unit for type unions;
  • expression of type bottom is assignable to any other type;
  • bottom type could be used only as return type of the function (out-only);
  • if function has return type bottom then all branches of the control flow either throw exceptions or return expression of type bottom;
  • if all branches of the control flow either throw exceptions or return expression of type bottom and function has no explicit return type then bottom type inferred as the result type;
  • two functional types are not assignable to each other if exactly one of them has return type bottom (?);
  • bottom type can't be used as the actual type parameter for the generic type.

rationale

Let's consider the function that always throws:

function alwaysThrows() {
    throw new Error("!");
}

and other function that uses it

function test(a: boolean) {
    return a ? 123 : alwaysThrow();
}

We expect that test should have type number instead of ( number | void )

In more sophisticated example that involves Promise type declarations:

declare class Promise<T> {
    catch<U>(
        handler: (reason: any) => U | Promise<U>
    ): Promise<T | U>;  // Note the union here (!)
    then<U>(
        fulfilled?: (result: T) => U | Promise<U>,
        rejected?: (reason: any) => U | Promise<U>
    ): Promise<U>
}

We expect that

promiseOfString.catch(function(e) {
   throw new BusinessError(e);
});

should have the type of Promise<string> instead of Promise<string | void>.

See petkaantonov/bluebird#589 (comment)

Possible explicit annotation that function always throws is using undefined as the type

function alwaysThrows(): undefined {
    throw new Error("!");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    CommittedThe team has roadmapped this issueFixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions