Replies: 30 comments 15 replies
-
With version 3, instead of maintaining a static Given the problems so far, I am seriously thinking of going back to manually editing the declaration file. I would really prefer to generate it dynamically though... I'll wait a little to see if the TypeScript team can move soon on the issue. |
Beta Was this translation helpful? Give feedback.
-
I did try your code with v3.0.6 and it works for me without complains. Maybe you are using a stricter TypeScript mode? I'll publish v3.0.6 in a minute so you can check if it makes a difference. |
Beta Was this translation helpful? Give feedback.
-
Tried the new version and it didn't fix the issue, I am using |
Beta Was this translation helpful? Give feedback.
-
The |
Beta Was this translation helpful? Give feedback.
-
It is a combination of |
Beta Was this translation helpful? Give feedback.
-
The TypeScript team got back to me yesterday but it's unclear whether this is going to be fixed or not. I guess we will have to wait a little more. Meanwhile, if you disable |
Beta Was this translation helpful? Give feedback.
-
it still compiles with the errors, i guess i will just wait. might have more issues. ill make another thread as i find them. |
Beta Was this translation helpful? Give feedback.
-
Can you try the new declaration file that's included in v3.0.8 and tell me if it helps? |
Beta Was this translation helpful? Give feedback.
-
Kind of, the red error line is gone, but typescript are recognizing them as |
Beta Was this translation helpful? Give feedback.
-
Yes, that is right. I am extending the Having said that, in the extending classes from WEBMIDI.js I do know the actual types used. So, I actually intend to create all those event types and assign them properly in the specific context of the library. I just haven't had the time yet. There are over 50 types of events that I need to sort through and dynamically insert into the jsdoc (because of the problem with the TypeScript compiler not supporting namespaced properties). This is on my todo list. However, it should not prevent you from using the library. You will just have to refer to the documentation more often. |
Beta Was this translation helpful? Give feedback.
-
are you aware of generics? |
Beta Was this translation helpful? Give feedback.
-
I will check it out. Thanks. |
Beta Was this translation helpful? Give feedback.
-
I've got a Typescript app and I'm attempting to update from v2 to v3 as well. I'm hitting a similar problem. I could force the types, but I can't seem to figure those out either. Maybe someone could push me in the right direction. input.addListener('noteon', (midi) => {
midi = midi as Message
// ^^ this doesn't seem to work... what should the type be?
const note = midi.note.number
const channel = midi.channel
const id = midi.target.id
}) I'd love to see the Typescript compatibility come together and I'd be happy to help if I can. |
Beta Was this translation helpful? Give feedback.
-
Just to be clear, I am committed to supporting TypeScript but I haven't worked on the event types just yet. Since v3, the If I can count on your help, it shouldn't be too hard to get it done right. Basically, if you had a little time to test the types before I release them, that would be awesome. I did not have any TypeScript beta testers. This may explain why early TypeScript support has been a bit wonky. I'll keep you posted. |
Beta Was this translation helpful? Give feedback.
-
Question: is it better for TypeScript developers to have one separate type for each dispatched event object or can they be combined? For instance, both In fact, a generic A few events contain their own particular properties ( Do you have examples of how it's done in well-known libraries? I want to do it right. Cheers! |
Beta Was this translation helpful? Give feedback.
-
I am relatively new to typscript myself. But i can certainly share my opinions.
No, I think typescript doesn't complain if you were to pass something that wanted an
I think I have seen some libraries that do this both ways. Im not sure there is a "best practice" in the "community". |
Beta Was this translation helpful? Give feedback.
-
That was my understanding too. However, from the developers perspective, it might get confusing. For instance, I could create a generic |
Beta Was this translation helpful? Give feedback.
-
Idealy we don't explicitly cast. Idealy we use what is returned. If that type has a I will test passing identically typed objects tomorrow and see if typescript wants to give me an error. functionally if typescript doesn't complain i don't see the need to add complexity. |
Beta Was this translation helpful? Give feedback.
-
I'm not sure I understand. When you use So, if you do not explicitly cast, how can TypeScript know ahead of time which type to expect? |
Beta Was this translation helpful? Give feedback.
-
There are 4 classes that dispatch events: Below, you will find, what I plan to add to the P.S. I put in comments which classes dispatch what. /**
* Input: closed, disconnected, opened,
* InputChannel: -
* Output: closed, disconnected, opened
* WebMidi: connected, disabled, disconnected, enabled, midiaccessgranted, portschanged
*/
export interface Event {
timestamp: DOMHighResTimeStamp;
type: string;
target: any;
}
/**
* Input: -
* InputChannel: -
* Output: -
* WebMidi: error
*/
export interface ErrorEvent extends Event {
error: any;
}
/**
* Input: activesensing, clock, continue, midimessage, reset, songposition, songselect,
* start, stop, sysex, timecode, tunerequest, unknownmessage
* InputChannel: allnotesoff, allsoundoff, midimessage, resetallcontrollers, channelaftertouch,
* localcontrol, monomode, omnimode, pitchbend, programchange
* Output: -
* WebMidi: -
*/
export interface MessageEvent extends Event {
message: Message;
value?: number | boolean;
rawValue?: number;
}
/**
* Input: -
* InputChannel: controlchange, controlchange-controllerxxx
* Output: -
* WebMidi: -
*/
export interface ControlChangeMessageEvent extends MessageEvent {
controller: {
number: number;
name: string;
};
subtype?: string
}
/**
* Input: -
* InputChannel: noteoff, noteon, keyaftertouch
* Output: -
* WebMidi: -
*/
export interface NoteMessageEvent extends MessageEvent {
note: Note;
}
/**
* Input: -
* InputChannel: nrpn, nrpn-databuttondecrement, nrpn-databuttonincrement, nrpn-dataentrycoarse,
* nrpn-dataentryfine, rpn, rpn-databuttondecrement, rpn-databuttonincrement,
* rpn-dataentrycoarse, rpn-dataentryfine
* Output: -
* WebMidi: -
*/
export interface ParameterNumberMessageEvent extends MessageEvent {
parameter: string;
parameterMsb: number;
parameterLsb: number;
} |
Beta Was this translation helpful? Give feedback.
-
Not sure if i updated the files correctly. I added them to both the cjs and esm files at the top and nothing appeared to change. they seem to make sense though, i don't know. maybe the reason why just appending the file isn't fixing it is because those types aren't defined at the implimentation? did you drop EDIT: also this is valid typescript (apparently).
so to answer your earlier question about if everything should have its own type im gonna say no. as long as the types definitions are the same it doesn't matter what they are called. |
Beta Was this translation helpful? Give feedback.
-
I'm just riffing here. But I've used a method similar to this article to create a Typescript interface that acts as a map between event types and the listener function. Then we use variable types to switch the second argument of import { Message, Note } from "../dist/cjs/webmidi.cjs";
/**
* Input: closed, disconnected, opened,
* InputChannel: -
* Output: closed, disconnected, opened
* WebMidi: connected, disabled, disconnected, enabled, midiaccessgranted, portschanged
*/
export interface Event {
timestamp: DOMHighResTimeStamp;
type: string;
target: any;
}
/**
* Input: -
* InputChannel: -
* Output: -
* WebMidi: error
*/
export interface ErrorEvent extends Event {
error: any;
}
/**
* Input: activesensing, clock, continue, midimessage, reset, songposition, songselect,
* start, stop, sysex, timecode, tunerequest, unknownmessage
* InputChannel: allnotesoff, allsoundoff, midimessage, resetallcontrollers, channelaftertouch,
* localcontrol, monomode, omnimode, pitchbend, programchange
* Output: -
* WebMidi: -
*/
export interface MessageEvent extends Event {
message: Message;
value?: number | boolean;
rawValue?: number;
}
/**
* Input: -
* InputChannel: controlchange, controlchange-controllerxxx
* Output: -
* WebMidi: -
*/
export interface ControlChangeMessageEvent extends MessageEvent {
controller: {
number: number;
name: string;
};
subtype?: string
}
/**
* Input: -
* InputChannel: noteoff, noteon, keyaftertouch
* Output: -
* WebMidi: -
*/
export interface NoteMessageEvent extends MessageEvent {
note: Note;
}
/**
* Input: -
* InputChannel: nrpn, nrpn-databuttondecrement, nrpn-databuttonincrement, nrpn-dataentrycoarse,
* nrpn-dataentryfine, rpn, rpn-databuttondecrement, rpn-databuttonincrement,
* rpn-dataentrycoarse, rpn-dataentryfine
* Output: -
* WebMidi: -
*/
export interface ParameterNumberMessageEvent extends MessageEvent {
parameter: string;
parameterMsb: number;
parameterLsb: number;
}
export interface InputEventMap {
'songposition': (event: MessageEvent) => void;
'songselect': (event: MessageEvent) => void;
'start': (event: MessageEvent) => void;
// etc
'clock': (event: MessageEvent) => void;
// etc
'noteon': (event: NoteMessageEvent) => void;
'noteoff': (event: NoteMessageEvent) => void;
'controlchange': (event: ControlChangeMessageEvent) => void;
}
class Input {
constructor() {}
addListener<T extends keyof InputEventMap>(event: T, listener: InputEventMap[T]): void {
// ...
}
}
const input = new Input()
input.addListener('noteon', (message) => {
message.note.number; // <-- all autocompleting and types are correct
}) |
Beta Was this translation helpful? Give feedback.
-
Okay... I got fed up of fighting and I decided to manually put together a new |
Beta Was this translation helpful? Give feedback.
-
Not sure it worked. I put it in |
Beta Was this translation helpful? Give feedback.
-
Sorry. I should have explained it better. You need to replace the content of |
Beta Was this translation helpful? Give feedback.
-
Ah ha! Once, I copied and renamed it to There is still not a type for Also, |
Beta Was this translation helpful? Give feedback.
-
You've added the types for |
Beta Was this translation helpful? Give feedback.
-
I just released v3.0.9 which incorporates the new type declarations. I improved a few things such as refining the types for the Let me know how it works for you guys. |
Beta Was this translation helpful? Give feedback.
-
It didn't work for me. I can't find a way to access |
Beta Was this translation helpful? Give feedback.
-
The generic |
Beta Was this translation helpful? Give feedback.
-
I am trying to add some listeners to my code.
connected
,disconnected
,noteon
andnoteoff
. in v2.5 i was doing the following for anoteon
event.I am using Typescript and it tells me
Parameter 'e' implicitly has an 'any' type
. This wasn't an issue before, Typescript understood what the callback was being passed. forconnected
we hadWebMidiEventConnected
and fordisconnected
we hadWebMidiEventDisconnected
. I don't havenoteon
ornoteoff
documented in my code (I might downgrade to find out).These are typescript errors exlusively as the code beind them seems to work.
Sidenote: Without changing any of my code (from 2.5 to 3) the
noteoff
listener doesn't seem to work. When I release a midi key anothernoteon
event is triggeredEDIT: the event sent to
noteon
wasInputEventNoteon
and the event fornoteoff
wasInputEventNoteoff
Beta Was this translation helpful? Give feedback.
All reactions