Skip to content

Suggestion: explicit type narrowing #9946

Closed

Description

To fix #5930 and #6474:

Syntax and use cases

let anything: any;
if (isFoo(anything)) {
  declare anything: Foo;
  anything.foo // valid and type-checkable
}

interface Foo {
  foo: number;
}

function isFoo(something: any): something is Foo {
    return typeof something.foo === "number"; 
}
let node: Node
if (node.nodeType === 1) {
   declare node: Element;
   node.addEventListener // valid
}
// Added on August 2, 2016
// Dog|House case from #9999
function fn(x: any) {
  if (x instanceof Animal) {
    declare x: Dog; // User knows better than the type system, so let it go explicitly
    x.woof(); // type-checked
  } else {
    declare x: House;
    // handle House case
  }
}
// Added on August 8, 2016
try {
  foo();
}
catch (err) {
  // when I'm absolutely sure that my error object will always be an instance of Error
  declare err: Error;
  console.error(err.messge) // compiler warns
}

Behavior

{
  declare anything: Foo;
  // `anything` is Foo in this block.
  // if type of `anything` is not narrow-able into Foo, it should be an error.
}

Why not existing type guards?

  1. any type cannot be narrowed by type guards. (User defined type guard function and type any #5930)
  2. Defining a new super-small function only for a single or two uses is not always preferable. (Allow inline type predicates #6474)

Workaround

Declare a new variable. var element = node as Element

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions