0

I'm assuming this is intentional behavior, but it's unexpected. Given the following:

interface Foo {
  foo: number
}

interface Bar {
  bar: Foo
}

const BAR = 'bar'
const BAR2: string = 'bar'

function getBar(bar: Bar): boolean {
  return bar[BAR].foo // error, typescript can discern the value of `BAR` and reports that `number` is not assignable to `boolean`.
}

function getBar2(bar: Bar): boolean {
  return bar[BAR2].foo // typescript appears to not be able to discern the value of `BAR2`
}

I would have expected Typescript to be abel to discern the value of BAR2 and thus, be able to discern the type and error on an invalid function return type like getBar is doing. But it appears Typescript only knows that BAR2 is a string.

NB: turning on noImplicitAny will expose a different error on getBar2 because there's no index signature on Bar

Can someone please shed some light on why the explicit typing on a const results in this behavior?

3
  • Can you please be a little more explilcit? Do you mean strings can be cast to booleans? Also, that's not really what the crux of the issue is, rather, why can't Typescript discern the value of the const since it's being set explicitly? Commented Apr 18, 2018 at 16:45
  • Ugh, nevermind. I made a mistake. Coercion, conversion, casting. It all means the same. I don't understand what "discern the value of BAR2" means. foo does not have the right type? What is wrong actually? Commented Apr 18, 2018 at 16:50
  • No worries. The issue is that Typescript can determine the value when explicitly initializing a const to a value without a type. But when one explicitly declares a type, it's no longer able to determine the explicit initialization. Commented Apr 18, 2018 at 18:06

1 Answer 1

4

TypeScript gave the variable BAR the type "bar" because that was its initializer. This means that bar[BAR].foo is number because bar.bar.foo is number and those things mean the same thing.

With BAR2, you explicitly overrode the inference so it has the type string instead of the type "bar". When you index an object by a string, you get an implicit any.

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

3 Comments

So I followed everything except for the "explicitly overrode the inference" - it's still a string, no? And it still should be able to discern the explicit value since it's initialized as such, right?
It's the type of the variable being the string literal type "bar" that causes the lookup to resolve to a known variable. The : string annotation means "This variable is of type string", so that resolution no longer occurs.
Ah. Got it. Cheers.

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.