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

Support multiple template literal string index signatures #45202

Closed
4 of 5 tasks
dwelle opened this issue Jul 27, 2021 · 2 comments
Closed
4 of 5 tasks

Support multiple template literal string index signatures #45202

dwelle opened this issue Jul 27, 2021 · 2 comments

Comments

@dwelle
Copy link

dwelle commented Jul 27, 2021

Suggestion

Support multiple template literal string index signatures (initial support of which was added in TS 4.4 #44512):

const config: {
	[a: `a.${string}`]: string[],
	[b: `b.${string}`]: number[]
} = {
	[`a.abc`]: ["a", "b"],
	[`b.def`]: ["c", "d"]
}

🔍 Search Terms

template literal strings index signatures

✅ 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.

📃 Motivating Example & Use Cases

Same use cases as single template literal index signature, but more useful.

One example are objects containing queries for databases/APIs that support it (Firebase Firestore...) for validation purposes.

For example, this is what an API to update Firestore documents which validates update paths could look like:

type BookDocument = {
	[chapterText: `chapter.${string}.text`]: string,
	[chapterAuthor: `chapter.${string}.authors.${string}`]: { name: string, email: string }
};

const {bookId, author, chapterId, chapterText} = req.params;

updateDoc<BookDocument>(
	firestore.collection("books").doc(bookId),
	{
		[`chapters.${chapterId}.text`]: chapterText,
		[`chapters.${chapterId}.authors.${author}`]: author
	}
)

Current best workaround is to define an overloaded function with [path, value] parameter pairs, but the downside is you can't supply a map or list of tuples (e.g. during class construction etc.).

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jul 27, 2021

Your second example seems to have more to do with the fact that a template string computed property doesn't create an index signature.

The first example works and correctly issues errors though.

So I'm not sure if I understand what the suggestion is here. Can you provide some more details?

@dwelle
Copy link
Author

dwelle commented Jul 27, 2021

Never mind. It just so happens I made a mistake when trying to define multiple template literal index signatures, where both resolved to the same template literal type. It looked something like this:

type T = {
	[q: `a.${string}.b`]: string,
	[q: `a.${string}.${string}`]: number
};

Which obviously shouldn't work.

The rest was confirmation bias and not looking for counter examples.

Sorry for wasting your time :).

(The first example contains a typo — it shouldn't be set to ["c", "d"] which doesn't type check indeed.)

@dwelle dwelle closed this as completed Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants