Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union types confound interface implementation checks #20983

Closed
bworline opened this issue Jan 3, 2018 · 2 comments
Closed

Union types confound interface implementation checks #20983

bworline opened this issue Jan 3, 2018 · 2 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@bworline
Copy link

bworline commented Jan 3, 2018

Why does this compile without error?

TypeScript Version: 2.6.1

Code

interface TestInterface {
  setName(name: string | Date): void;
  setAge(years: number | null | undefined): void;
}

// the next line should give build-time error:  
// Class 'TestClass' incorrectly implements interface 'TestInterface'.
class TestClass implements TestInterface { 
  setName(name: string) { // signature does not match interface
    if (name.slice(0, 1) === 'B') {
      console.log('Great name.');
    }
  }
  setAge(years: number) { // signature does not match interface
    console.log(years.toExponential());
  }
}

let x: TestInterface = new TestClass();
x.setName(new Date()); // causes runtime error
x.setAge(null); // causes runtime error

Expected behavior:
Should get a build-time error: Class 'TestClass' incorrectly implements interface 'TestInterface'.

Actual behavior:
No build-time error, and a run-time error later.

@ahejlsberg
Copy link
Member

ahejlsberg commented Jan 3, 2018

It compiles without error because parameters of methods are checked bivariantly. If you change the interface declaration to use property syntax

interface TestInterface {
  setName: (name: string | Date) => void;
  setAge: (years: number | null | undefined) => void;
}

and compile with --strictFunctionTypes (or just --strict) you will see the expected errors. See #18654 for rationale and more information.

@ahejlsberg ahejlsberg added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jan 3, 2018
@bworline
Copy link
Author

bworline commented Jan 3, 2018

Thank you for the explanation and the work-around. Much appreciated.

I do hope that you will continue to explore the stricter mode of --strictFunctionTypes that includes methods. I'm sure that you can appreciate that co/contra/bi-variance is a complex topic that is best left to the compiler to figure out and tell me when I've made a mistake--meaning that most devs are not thinking about these nuances when coding. My example was meant to demonstrate how easy it is to fall into this particular trap without realizing it and running into a run-time failure later.

@bworline bworline closed this as completed Jan 3, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants