question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improve support for Symbol.toPrimitive

See original GitHub issue

Presently, TS limits index types to ‘string’, ‘number’, ‘symbol’, or ‘any’. That’s fine, but consider the following:

class Foo {
    [Symbol.toPrimitive](): number {
        return 1;
    }
}

var x = ['a','b','c'];
var f = new Foo();
x[f];

We give the error an index expression argument must be of type ... on the array access.

Foo is for all intents and purposes a wrapper around the number 1 (close to new Number(1)), yet it cannot be used to index an array, since Foo itself is not of type number, string, symbol, or any. We could do extra type-checking to see if an object has a user-defined Symbol.toPrimitive and consider its return types when checking type-coercing operations (after all, if you’ve opted in to using Symbol.toPrimitve it’s probably part of your goal to gain this behavior), such as indexing or mathematics operators.

Building on this, we currently don’t support the coercion of Number or String classes to their respective primitive types (which are a specialization of the above issue but which applies to ES5 and ES3 output). Presently one can’t do this:

function add(a: string, b: string): number {
  var x = new Number(a);
  var y = new Number(b);
  return x + y;
}
add('10e4', '0x8');

Because since neither x nor y is the ‘number’ (or ‘string’) primitive type, the addition operation is not allowed. Though it’s still valid js (and without the usage of the Number class, the addition would result in ‘10e40x8’!).

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:15
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
CMCDragonkaicommented, Oct 16, 2021

I thought I might try the hack where you intersect with a primitive. This works for alot of cases.

type Id = IdInternal & string;

class IdInternal {
  // psuedo code
  [Symbol.toPrimitive]() {
    return 'abc';
  }
}

const id = new IdInternal as Id;

const obj = {};
obj[id] = 3;

However I found that strings intersection results in conflicts with the main type. Especially in terms of index accessors:

// TS now thinks this is `never`
id[0]

So it would be nice to support some way of doing this. Although I noticed that Date has the same problem atm.

1reaction
bschlenkcommented, Dec 5, 2020

I think this would make writing isomorphic packages that use setTimeout easier (https://github.com/microsoft/TypeScript/issues/842). You’d be able to assign the Timeout type to a number.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Symbol.toPrimitive - JavaScript - MDN Web Docs
The Symbol.toPrimitive well-known symbol specifies a method that accepts a preferred type and returns a primitive representation of an ...
Read more >
What Is Meant by "[@@toPrimitive]()" in JavaScript? - Designcise
A " Symbol.toPrimitive() " method is the first object method that's called by all type coercion algorithms. Therefore, it can be used to...
Read more >
Confusion related to Symbol.toprimitive method in js
No, Symbol.toPrimitive is a Symbol, not a function. It's used as the key of an object property whose value should be a function,...
Read more >
JavaScript | symbol.@@toPrimitive() function - GeeksforGeeks
The symbol.@@toPrimitive() is an inbuilt function in JavaScript which is used to converts a given symbol object to a primitive value. Syntax:.
Read more >
Object to primitive conversion - The Modern JavaScript Tutorial
obj[Symbol.toPrimitive] = function(hint) { // here goes the code to convert this object to a primitive // it must return a primitive value ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found