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

Specific type revert to string with dynamic key #60896

Closed
Zamralik opened this issue Jan 1, 2025 · 8 comments
Closed

Specific type revert to string with dynamic key #60896

Zamralik opened this issue Jan 1, 2025 · 8 comments
Labels
Duplicate An existing issue was already created

Comments

@Zamralik
Copy link

Zamralik commented Jan 1, 2025

πŸ”Ž Search Terms

dynamic key type

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about dynamic keys

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.7.2#code/GYVwdgxgLglg9mABAUwB4EMC2AHANsgRgB4BpFVKZMAEwGdFaoAnGMAcwD4AKAa2QE8AXIhIAaRADd0uEMmHgeYOAHcwASmEBvRAG0+-RKxEBdeWEUqkAXwBQmmwEgmyKCCZJtegacnTZiKwBuG1sbUEhYBHIsPGQAJlJyShp6RhZ2bn1hMV8ZOUQFJVUNRAAlZAg4JmpScULLDjtHZ1d3RE99Hyk8gOCrIA

πŸ’» Code

function example1<K extends string>(key: K, value: unknown): { [key in K]: unknown }
{
	return { [key]: value };
}

function example2<K extends string>(key: K, value: unknown): Record<K, unknown>
{
	return { [key]: value };
}

πŸ™ Actual behavior

Type '{ [x: string]: unknown; }' is not assignable to type '{ [key in K]: unknown; }'.(2322)
Type '{ [x: string]: unknown; }' is not assignable to type 'Record<K, unknown>'.(2322)

The type of the key is K but reverts to string

πŸ™‚ Expected behavior

The type of the key is preserved as K.

Additional information about the issue

No response

@MartinJohns
Copy link
Contributor

This is working as intended. Duplicate of #53912.

This call is perfectly valid, but your functions would return incomplete objects:

example1<"a" | "b">("a", "value");

@Zamralik
Copy link
Author

Zamralik commented Jan 1, 2025

Thanks. I understand the cause of the issue now.

But we can't do things like

function example(key: infer K satisfies string, value: unknown): { [key in K]: unknown }
{
    return { [key]: value };
}

Or

function example<K extends unique string>(key: K, value: unknown): { [key in K]: unknown }
{
    return { [key]: value };
}

These syntax do not exists.

@MartinJohns
Copy link
Contributor

MartinJohns commented Jan 1, 2025

You can't do that because it's simply not supported (yet?). There's an open issue for this: #27808

@Zamralik
Copy link
Author

Zamralik commented Jan 1, 2025

Though it appear similar, it's not exactly the same.
#27808 is about needing to pick a type among a list, here it's more needing to as const the value when used.
If only we could infer outside ternary and use satisfies in type.

@MartinJohns
Copy link
Contributor

It is exactly the same. You want to limit the type argument to a single value, disallowing unions.

If only we could infer outside ternary and use satisfies in type.

It would still need to be a generic type, and generic types can be provided by the caller explicitly.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jan 2, 2025
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jan 5, 2025
@Zamralik
Copy link
Author

Zamralik commented Jan 6, 2025

It is exactly the same. You want to limit the type argument to a single value, disallowing unions.

If only we could infer outside ternary and use satisfies in type.

It would still need to be a generic type, and generic types can be provided by the caller explicitly.

In this example it wouldn't be possible for the caller to provide the type explicitly.
The issue is that you would be able to get a variable with a non-const type.

function example(key: infer K satisfies string, value: unknown): { [key in K]: unknown }
{
    return { [key]: value };
}

@MartinJohns
Copy link
Contributor

In this example it wouldn't be possible for the caller to provide the type explicitly.

Only because it's arbitrary syntax with nothing behind it. When implemented the argument would still need to be generic.

And you could still always do this:

declare const myKey: "a" | "b"
example(myKey, value);

And according to the type system the object would need to have two properties.

Again, what you want is #27808.

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

4 participants