question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Variant accessors for index signatures and mapped types

See original GitHub issue

Suggestion

🔍 Search Terms

variant accessors index signatures record

✅ 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

Support for having Variant Accessors with index signature.

📃 Motivating Example

// Simple  usage

interface NumberMap { 
  get [k: string](): number;
  set [k: string](val: string | number);
}

const a: NumberMap = {} 

a.test = '1';
a.test === 1;


// more complex

// makes number properties of an object to allow set `string`
type MakeStringAsNumber<T extends Record<string, any>> = {
  get [ K in keyof T]: T[K]
  set [ K in keyof T]: T[K] extends number ? T[K] | string : T[K]
}

declare const a: MakeStringAsNumber<{ a: boolean, b: number, c: string }>
a.b = '42'; // I want to have this avalible

a.c = '112'

// @ts-expect-error 'a' is boolean
a.a = '2'

💻 Use Cases

The use case for this feature is vue 3 reactivity.

In Vue 3 there’s Ref<T> (simplified as { value: T}) and Reactive<UnwrappedRef<T>> (unwraps {value: T} to T, recursive)

This feature would allow us to generate a type which can accept a Ref<T> | T

Basically:

const r = ref({ a: 1} )

r.value.a = 1

const a = reactive(r)
a.a // 1

On a reactive/ref object the set in typescript must be UnwrappedRef<T> which is not true, because when you assign to a reactive it will unwrap the value:

const r = ref({a:1});
const a = ref({
  r
}) // results in `{ r: { a: 1 } }` 

a.r = r; // typescript error  because `r` is `Ref<T>` instead of `UnwrappedRef<T>`, but it works at runtime.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:43
  • Comments:14 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
thw0rtedcommented, Nov 8, 2021

I don’t mean to be overly critical, but your API reads like your first language is Ruby. Proxy abuse like that doesn’t seem like the kind of thing TS should be encouraging. What’s wrong with database.get("admin.settings.defaultPage")? If you want to encode the database key hierarchy for type-checking, you can use conditional types to generate a union of template literal strings from an interface.

2reactions
ccheraacommented, Nov 9, 2021

Thank you for your example, this helps make my code much better. But I still believe that being able to get a Promise and set a value will make it even better.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Index signature with separate types for getters and setters
Variant accessors do not currently apply to index signatures or mapped types. There is an existing feature request at ...
Read more >
Playground Example - Use Index Accessors for Index Signatures
This type uses an index signature to indicate that you can ask for any string and you will either get a string of...
Read more >
Mapped Types - Learn TypeScript w/ Mike North
Mapped allow types to be defined in other types through a much more flexible version of an index signature. We'll study this type...
Read more >
Google TypeScript Style Guide
Type System: Type Inference: Null vs Undefined: Structural Types vs Nominal ... Types / index signatures ({[key: string]: T}): Mapped & Conditional Types...
Read more >
Overview - TypeScript
In TypeScript 3.4, the readonly modifier in a mapped type will ... If X contains a string index signature, keyof X is a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found