1

In JavaScript, plain old objects can take all kinds of abuse. For example you can write:

var obj = {};
var func = new Function() {};
obj[func] = 5; // totally fine
obj[func]; // returns 5

With some creativity you could write a generic class SimpleSet<T> that might use an object as its backing store in JavaScript or TypeScript. One straightforward way may involve writing something like this:

public add(val: T) {
  this._dict[val] = val;
}

Which doesn't work in TypeScript. Why? More permissive versions of add work, see add2 and add3.

class SimpleSet<T> {
  _dict: Object;
  constructor() {

  }

  // error:
  public add(val: T) {
    this._dict[val] = val;
  }

  // no error:    
  public add2(val: T) {
    this._dict[val as any] = val;
  }

  // no error:
  public add3(val: any) {
    this._dict[val] = val;
  }
}

With add, two errors appear:

Type 'T' is not assignable to type 'Object[T]'.

Type 'T' cannot be used to index type 'Object'.

enter image description here

Why?

4
  • 2
    Your function creation syntax is wrong, but do you realize setting a function as the key to a JS object will cast the function to a string, creating a key something like this: "function (){}"? Commented Mar 13, 2017 at 21:08
  • var obj = {}; var key1 = {prop1:'val1'}; var key2 = {prop2:'val2'}; obj[key1] = "hello"; console.log(Object.keys(obj)); will log ["[object Object]"]. Logging obj[key2] will show "hello" because the toString() of both objects are the same. Commented Mar 13, 2017 at 21:20
  • You've gotten pretty far on something that doesn't work... Commented Mar 13, 2017 at 22:19
  • I wasn't trying to make a workable set here (this would be insane in JS too), but trying to figure out the rule for any being allowed vs Object being disallowed as a type. I see now I was under the mistaken belief that any means "allow all types", instead of "opt out of type checking." Commented Mar 15, 2017 at 15:17

1 Answer 1

5

TypeScript doesn't let you because it doesn't work, which is a pretty decent reason as far as things go.

The indexing keys of JavaScript objects are always (always) strings. Indexing by other sorts of things coerces the key to a string and then looks up by that. For example, as pointed out in comments, indexing by an object produces the key "[object Object]"

You can use the ES6 Map object for a working object-to-value store.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer. I'm still fooling around with TS, trying to figure out what's allowed and what's not. Obviously this set implementation would be silly in JS too. I thought it was interesting that any is allowed as an index type, yet Object is not. I see now I was under the mistaken belief that any meant "allow all types", instead of "opt out of type checking."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.