1

If you need a generic type that can be read as type T, you can use X extends T. That means when you read the value you can treat it as T. E.g.

function foo<X extends number>(x: X) {
  console.log(Math.sqrt(x)); // OK because x can be treated as a number when read.
}

How do you do the equivalent for writing to a value?

function foo<X extends number>(x: X) {
  x = Math.sqrt(2); // This doesn't work.
}

I want this behaviour:

const a: number | undefined = 5;
const b: string | number = "hello";
const c: string | undefined = "goodbye";

foo(a); // Ok
foo(b); // Ok
foo(c); // Error!
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • Because `Math.sqrt` returns a `number`, but you've said that `X` need only be assignable to `number`. – Aluan Haddad Sep 24 '20 at 10:24
  • The only way `foo(b)` could ever be "Ok" is if `foo` checks at runtime to see if it is a number before using it as one. – ccarton Sep 24 '20 at 10:46
  • @AluanHaddad: Yes I know *why* it doesn't work. I'm asking *how to make it work*. – Timmmm Sep 24 '20 at 10:46
  • You can't without a type assertion but the example seems contrived so it's hard to suggest anything. I assume you're not doing this merely to reuse `x` instead of creating a new variable. – Aluan Haddad Sep 24 '20 at 10:47
  • 1
    You're right - this is for use in [a more complicated function](https://stackoverflow.com/questions/64035397/type-safe-field-assignment). I was trying to keep things simple for the question. – Timmmm Sep 24 '20 at 10:52

1 Answers1

-1

Generic type X extends T means X has a superset interface of T. So X is number's superset. You can't set a subset interface to a superset.

extends is not inherit

lei li
  • 1,244
  • 1
  • 12
  • 35