Element implicitly has an 'any' type

Viewed 1511

This demo makes typeof Symbol.toStringTag type symbol:

const promise = Promise.resolve();
const toStr: typeof Symbol.toStringTag | void = typeof Symbol === 'function' ? Symbol.toStringTag : undefined;

if (toStr) {
    console.log(promise[toStr] === 'Promise');
}

And results in error:

Element implicitly has an 'any' type because expression of type 'symbol' can't be used to index type 'Promise'.(7053)

Is there a way to narrow down toStr symbol type instead of using symbols explicitly like promise[Symbol.toStringTag]?

3 Answers

Stated that I'm not getting the same error, but I got a true printed on my console with following compilerOptions

"compilerOptions": {
    "declaration": true,
    "module": "commonjs",
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es6"
}

Since you know that typeof Symbol.toStringTag === "symbol", why not?

const promise = Promise.resolve();
const toStr: symbol | void = typeof Symbol === "function" ? Symbol.toStringTag : undefined;

if(toStr) console.log(promise[toStr] === "Promise");

Once said that I think the key is suppressImplicitAnyIndexErrors compile option. Don't know if it is a reasonable compromise for you.

Hope this helps

As you've noticed, typeof Symbol.toStringTag is just symbol, which isn't specific enough for your purposes. The unique symbol type is more specific, but I believe it's only for user-defined Symbols.

Would it meet your needs to use use an accessor function, rather than storing the symbol?

const promise = Promise.resolve();

interface StringTaggable {
  readonly [Symbol.toStringTag]: string;
}

const toStringTag =
  typeof Symbol === 'function' ? (o: StringTaggable) => o[Symbol.toStringTag] : undefined;

if (toStringTag) {
    console.log(toStringTag(promise) === 'Promise');
}

This has been a subject of a long passionate discussion on the TypeScript github. There are a few hacky ways of doing this but you will not be able to narrow the symbol type the way you can narrow down string to a string literal anytime soon :/

Related