0

Illustration

export interface IEventDef {
    ready: any,
}

export interface IIPCMessage {
    eventType: keyof IEventDef,
    data: IEventDef[this['eventType']]
}

interface IMessageHandlers {
    [eventName: keyof IEventDef]: (data: ) => void
}

Question

As per the illustration giving a string index signature for an interface! As below:

interface IMessageHandlers {
    [eventName: keyof IEventDef]: (data: /*HOW_TO_REF_eventName*/) => void
}

How can we reference the eventName in my example? Or the index property name! Of the same line

In my exact code I wanted to do this:

interface IMessageHandlers {
    [eventName: keyof IEventDef]: (data: IEventDef[thisLineProp]) => void
}

Which would give a great affinity! any way?

To clear better I'll take this snippet below!

export interface IEventDef {
    ready: any,
} 

export interface IIPCMessage {
    eventType: keyof IEventDef,
    data: IEventDef[this['eventType']] // <<= here
}

In that example I was able to reference the same interface with this keyword! Which allow great type affinity! And it allowed nice typing precision!

What about referencing and getting the property name of the same line from the index signature?

Update

I noticed that I just met the

An index signature parameter type must be either 'string' or 'number'.ts(1023)`

Error!

And I changed the code to

type IMessageHandlers = {
    [eventName in keyof IEventDef]: (data: /*REF_THE_PROP_NAME?*/) => void
}

And I go with the question for this?

Salim Djerbouh
  • 10,719
  • 6
  • 29
  • 61
Mohamed Allal
  • 17,920
  • 5
  • 94
  • 97
  • Can you provide an example of how you want to use it? It's unclear from the invalid typings what the expected result is. If I understand the problem so far, your last example is very close if you replace `/*REF_THE_PROP_NAME?*/` with `eventName` (assuming you want `data` to be typed the same as the key name) – skovy Oct 18 '20 at 18:09
  • Yea that what was it! I want to use on the second part the same name as the property! So From a usage point! When the object property is chosen! The mapped element will have automatically it's type inferred and correctly and with precision! And As you mentionned! i just had to use `eventName`! But at first i tried it, but in the interface! And with literal strings! and they are just not supported! And i didn't try with the `in` syntax. And that was my bad hhh! Any thoughts about when we need an interface!? Besides code generation! Thank you a lot sir – Mohamed Allal Oct 18 '20 at 19:10

1 Answers1

2

You are almost there actually. eventName holds the type you want.

type IMessageHandlers = {
    [eventName in keyof IEventDef]: (data: eventName) => void
}

Playground Link

Eldar
  • 9,781
  • 2
  • 10
  • 35
  • I was just there! i tried it ! However it was in the interface case! In the interface case we don't have it! And it make sense! I forget about the string only error! And unless they add support for `in` and the support for literal ! There is nothing that we can do! And in short this is possible through the `in` syntax! And we can use it in object literals! And we miss this on Interfaces! There was consideration for it! https://github.com/microsoft/TypeScript/issues/5683! It may spawn somewhere in the future! Thank you a lot Sir! And would appreciate any more thoughts! – Mohamed Allal Oct 18 '20 at 18:58
  • For interfaces and the problem of literal support! We can always generate the interfaces! And we can have a plugin for it too! through the use of AST (ts-morph is a good choice). – Mohamed Allal Oct 18 '20 at 19:03