Skip to content

Typescript 4.7 thinks keyof interface may contain a symbol #49261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bschlenk opened this issue May 26, 2022 · 3 comments
Closed

Typescript 4.7 thinks keyof interface may contain a symbol #49261

bschlenk opened this issue May 26, 2022 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@bschlenk
Copy link

Bug Report

πŸ”Ž Search Terms

Implicit conversion symbol fail runtime

πŸ•— Version & Regression Information

  • This changed between versions 4.6.* and 4.7.*

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

interface Property<T> {
  name: keyof T
}

interface ThingA {
  a: string
  b: string
}

interface ThingB {
  c: string
  d: string
}

function Filter<T extends ThingA | ThingB>(properties: Property<T>[]) {
  return properties.map((property) => `input-${property.name}`) // <-- Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.(2731)
}

πŸ™ Actual behavior

Typescript thinks that property.name here may be a Symbol. I guess maybe this makes sense since T extends ThingA | ThingB wouldn't prohibit a ThingC interface that extends ThingA with a symbol property. But I'd expect this new error to pop up in a lot more places in my codebase, but I only see it in this one spot.

I'm not sure in what circumstances this error is triggered, or how to work around it. I'd rather not add String(...) around the property because that's unnecessary extra runtime code.

πŸ™‚ Expected behavior

Because this doesn't fail in TS < 4.7, I'd expect it not to suddenly start failing.

@MartinJohns
Copy link
Contributor

MartinJohns commented May 26, 2022

Related: #49071 (was mentioned there)
Potentially fixed by #49107.

The suggestion by Daniel Rosenwasser was to write string & keyof T.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label May 26, 2022
@RyanCavanaugh
Copy link
Member

This is a correct error because this function crashes on legal inputs:

const m: { a: string, b: string, [Symbol.iterator]: ""} = { a: "", b: "", [Symbol.iterator]: ""};
Filter<typeof m>([{name: Symbol.iterator}]);
Uncaught (in promise) TypeError: Cannot convert a Symbol value to a string
    at <anonymous>:2:59
    at Array.map (<anonymous>)
    at Filter (<anonymous>:2:23)
    at <anonymous>:5:1

@bschlenk
Copy link
Author

Thanks @RyanCavanaugh that makes sense! And thanks for the string & keyof T suggestion Martin, that works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants