You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
IMidiSetTempoEvent eventually extends TValue which can be a lot (see extending type chain below). This make it extremely hard to determine which event we're looking when have file of type IMidiFile.
For example I have a function that takea a IMidiFile as input first the type IMidiFile needs to be derived as it's not exported , i.e.:
# So now IMidiFile can be used in the codebase that imports midi-json-parser
export type IMidiFile = Awaited<ReturnType<typeof parseArrayBuffer>>;
const someFunction = (file: IMidiFile) => { ... }
IMidiFile contains the tracks, typed as Tracks[][], the Tracks Type itself is not exported hence should also be derived, but is a bit more complex:
# Make a custom type that can get the type of a list type (i.e. Unpacks<Tracks[]> will become Tracks)
type Unpacked<T> = T extends (infer U)[] ? U : T;
# Double unpack Tracks[][] to get the Tracks type:
export type Tracks = Unpacked<Unpacked<IMidiFile['tracks']>>;
Now we can Tracks an input type for a function in our own codebase. If we create a loop over the events in a track, it's difficult to get the typing right for that event. It might be possible to do the following:
if('setTempo' in Event){
microsecondsPerQuarter = Event.setTempo.microsecondsPerQuarter;
} }
But that will give a type error, because the type where 'setTempo' exists on is IMidiSetTempoEvent, which extends IMidiMetaEvent, which extends IValueMap which have string keys and TValue as value. See the following chain:
which basically means IMidiSetTempoEvent can have any key, and can have any value of TValue. So with our check 'setTempo' in Event TypeScript can't simplify the type because 'setTempo' is both a valid key for IMidiSetTempoEvent and IValueMap (because it fits the key type string).
So accessing Event.setTempo.microsecondsPerQuarter will give an error because setTempo can also be a TValue, and TValue doesn't specify an object so it will error saying it can't access microsecondsPerQuarter, i.e. the error:
Property 'microsecondsPerQuarter' does not exist on type 'string | number | boolean | RegExp | ArrayBuffer | IValueArray | Float32Array | Float64Array | Int8Array | ... 14 more ... | { ...; }'.
Property 'microsecondsPerQuarter' does not exist on type 'string'
This makes it very difficult to properly check for an event and have the proper typing of the event to handle it, because basically every event becomes a big IValueMap which can be almost anything (except for an object).
The text was updated successfully, but these errors were encountered:
Short version:
Long version:
To take one event as example:
IMidiSetTempoEvent
IMidiSetTempoEvent
eventually extendsTValue
which can be a lot (see extending type chain below). This make it extremely hard to determine which event we're looking when have file of typeIMidiFile
.For example I have a function that takea a IMidiFile as input first the type
IMidiFile
needs to be derived as it's not exported , i.e.:IMidiFile
contains the tracks, typed as Tracks[][], the Tracks Type itself is not exported hence should also be derived, but is a bit more complex:Now we can Tracks an input type for a function in our own codebase. If we create a loop over the events in a track, it's difficult to get the typing right for that event. It might be possible to do the following:
But that will give a type error, because the type where 'setTempo' exists on is
IMidiSetTempoEvent
, which extends IMidiMetaEvent, which extendsIValueMap
which have string keys andTValue
as value. See the following chain:which basically means
IMidiSetTempoEvent
can have any key, and can have any value of TValue. So with our check'setTempo' in Event
TypeScript can't simplify the type because 'setTempo' is both a valid key forIMidiSetTempoEvent
andIValueMap
(because it fits the key type string).So accessing
Event.setTempo.microsecondsPerQuarter
will give an error because setTempo can also be a TValue, and TValue doesn't specify an object so it will error saying it can't accessmicrosecondsPerQuarter
, i.e. the error:This makes it very difficult to properly check for an event and have the proper typing of the event to handle it, because basically every event becomes a big IValueMap which can be almost anything (except for an object).
The text was updated successfully, but these errors were encountered: