Skip to content
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

Generic template literal index does not resolve value type #50030

Open
zachkirsch opened this issue Jul 25, 2022 · 4 comments Β· Fixed by #53066
Open

Generic template literal index does not resolve value type #50030

zachkirsch opened this issue Jul 25, 2022 · 4 comments Β· Fixed by #53066
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@zachkirsch
Copy link

Bug Report

πŸ”Ž Search Terms

template string key generic "is not assignable to type"

πŸ•— Version & Regression Information

  • This changed between versions 4.6.4 and 4.7.4

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// ObjectWithUnderscoredKeys creates an object where:
//   Keys are the strings in K, except each with an underscore prefix
//   Values are all `true`
export type ObjectWithUnderscoredKeys<K extends string> = {
    [k in K as `_${k}`]: true;
};

// it works without generics
function nonGenericTest(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<"foo" | "bar">, key: "foo" | "bar") {
  const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
}

// but not with generics
function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<K>, key: K) {
  // ERROR:
  // Type 'ObjectWithUnderscoredKeys<K>[`_${K}`]' is not assignable to type 'true'.
  //   Type 'ObjectWithUnderscoredKeys<K>[`_${string}`]' is not assignable to type 'true'.
  const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
}

πŸ™ Actual behavior

In the generic function genericTest, indexing into the object doesn't yield a value with the type true.

πŸ™‚ Expected behavior

In the generic function genericTest, indexing into the object should yield a value with the type true.

Related issues

This seems similar to #48983, but that was marked as Working as intended and the behavior in this example doesn't seem like it should be intended.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jul 28, 2022
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.9.0 milestone Jul 28, 2022
@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label Feb 1, 2023
@typescript-bot typescript-bot added the Fix Available A PR has been opened for this issue label Mar 2, 2023
@zachkirsch
Copy link
Author

Thanks @weswigham !!

@Andarist
Copy link
Contributor

@zachkirsch FYI, the "fix" for this will get reverted: #57202

@weswigham weswigham reopened this Jan 29, 2024
@ahejlsberg
Copy link
Member

ahejlsberg commented Jan 30, 2024

It's not clear to me this is an issue we want to fix. In the issue example, every property is of type true and we could consider recognizing that regardless of the key type. But that's not really a particularly common scenario, and anyway is better handled by just writing Record<`_${K}`, true>.

In mapped types where the template type actually depends on the iteration type, such as

type Foo<T extends string> = {
    [K in T as `_${K}`]: K;
}

to understand the constraint of Foo[X] for some generic type X we would need to create a reverse mapping that somehow strips the leading underscore from X. That's non-trivial and would work only because the as clause type is perfectly reversible in this example. Quite often as clause types aren't, and then there's nothing we can do. I'm not convinced it is worth the effort do attempt any of this.

@ahejlsberg ahejlsberg added Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone labels Mar 27, 2024
@ahejlsberg ahejlsberg removed this from the TypeScript 5.5.0 milestone Mar 27, 2024
@ahejlsberg
Copy link
Member

Re-labeling as suggestion and un-assigning myself.

@ahejlsberg ahejlsberg removed their assignment Mar 27, 2024
@RyanCavanaugh RyanCavanaugh added the Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature label Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
6 participants