1

Simplified Examples:

Variable type narrowing

let a: string | number | boolean;
let b: string = '';
a = b;

This works and there are no warnings. However, if the example were:

let a: (arg: string | number | boolean, record) => boolean;
let b: (arg: string, record) => boolean = (arg, record) => record.name.indexOf(arg) === 0;
a = b;

This results in a warning Type '(arg: string) => any' is not assignable to type '(arg: string | number | boolean) => any'.

I'm wondering why this is since b's type requrement is a subset of a's.

In practice, there's a React library I'm using and a component's prop requires an anonymous function with a's signature but I need to use b's signature otherwise indexOf will complain. How do I make the narrowing behavior of functions behave similarly to the variable's?

Thanks.

Alex
  • 3,441
  • 4
  • 18
  • 30
  • 1
    Erm, why would the function be assignable here? A function that takes `string | number | boolean` should be callable with either. However, a function that only takes *one* of these defintely cannot be callable with either. Consider `x => x.charCodeAt(0)` - that function can *only* be called with a string. So, if you assign it to something that will be called as `fn(true)` or `fn(42)` then you'd get an error. Because those are not strings. The function is thus not callable with `string | number | boolean` as an argument. – VLAZ Jan 23 '23 at 21:30
  • obligatory: [Difference between Variance, Covariance, Contravariance and Bivariance in TypeScript](https://stackoverflow.com/questions/66410115/difference-between-variance-covariance-contravariance-and-bivariance-in-typesc) – Tobias S. Jan 23 '23 at 21:33
  • Functions are *contravariant* in their argument types for reasons of type safety, as mentioned in the comments and the linked questions/answers. – jcalz Jan 23 '23 at 21:48

0 Answers0