Skip to content

Fixed keys should not need to be a subset of dynamic keys #43057

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
4 of 5 tasks
danielo515 opened this issue Mar 3, 2021 · 4 comments
Closed
4 of 5 tasks

Fixed keys should not need to be a subset of dynamic keys #43057

danielo515 opened this issue Mar 3, 2021 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@danielo515
Copy link

Suggestion

I think it should be possible to have fixed properties on a dictionary that doesn't need to match the type of the generic ones, or the other way round: that generic values should not be a superset of the fixed values

🔍 Search Terms

dynamic keys, static keys, mixing static and dynamic keys

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

So, in terms of code, I want to be able to type this:

type X = { startDate: string, [name: string]: number  }

However, typescript does not understand that the fixedKey startDate doesn't need to match the other generic key value pair, so you are forced to write it like this:

type X = { startDate: string, [name: string]: number| string }

💻 Use Cases

Adding dynamic keys to objects in javascript is quite common, and they don't need to match the type of existing keys. Many times you have a set of well known keys mixed with other dynamic keys, and you only care about the fixed ones and their type.
With destructuring is quite easy taking apart the known keys from the dynamic ones

const { fixedKey, knownKey, ...otherKeys} = someObject

So having all the "otherKeys" object have a mixed type just because fixedKey and knownKey didn't matched the type of the dynamic keys is an unnecessary trouble.

@MartinJohns
Copy link
Contributor

Indexed types with known properties are already unsound, and your suggestion would just worsen the situation by introducing the potential errors to not only the known properties, but to any properties accessed with the indexer.

const x: X = { startDate: "example" };

const key: string = "startDate";
x[key] = 123;

x.startDate; // Compile time type is string, runtime type is number;

@danielo515
Copy link
Author

But that is something the compiler should be able to catch. You already have the startDate as a constant string so it knows that you are trying to add an invalid type to a static defined prop.
But I see that, for some runtime values, you have no way to know if a string contains startDate or not.

Should this be possible using symbols then?

@RyanCavanaugh
Copy link
Member

Duplicate #17867, #7765, others.

You can represent this with an intersection type instead.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Mar 3, 2021
@danielo515
Copy link
Author

Yes, it is a duplicate of those.
Sadly you can't use an intersection type for this. Sure, you can declare it, but you can not type anything with that value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants