Open FiniteSingularity opened 1 year ago
I just started putting together a PR that adds a properly typed outputVariables
and a semi-typed inputVariables
to the RequestBatchRequest
type. I'll work a bit on the inputVariables
and submit a PR soon, but if folks want to give it a try, you can find the branch here: https://github.com/FiniteSingularity/obs-websocket-js/tree/feature/adds-input-output-vars
One issue I am seeing is that of enforcing type safety. About the best option I can come up with is this:
export declare type RequestBatchRequest<T = keyof OBSRequestTypes> = T extends keyof OBSRequestTypes ? OBSRequestTypes[T] extends never ? {
requestType: T;
requestId?: string;
outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : {
requestType: T;
requestId?: string;
requestData: Partial<OBSRequestTypes[T]>;
inputVariables?: Partial<OBSRequestTypes[T]>;
outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : never;
requestData
to must be a Partial<OBSRequestTypes[T]>
because the keys we replace using inputVariables
will no longer exist in requestData
. What we really need is for the union of requestData
and the optional inputVariables
to be an OBSRequestTypes[T]
. I've tried (unsuccessfully) to do this in a few ways, for example, letting inputVariables
be a Record<string, string>
, then using Omit
on those keys for requestData
:
export declare type RequestBatchRequest<T = keyof OBSRequestTypes, S = Record<string, string>> = T extends keyof OBSRequestTypes ? OBSRequestTypes[T] extends never ? {
requestType: T;
requestId?: string;
outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : {
requestType: T;
requestId?: string;
requestData: Omit<OBSRequestTypes[T], keyof S>;
inputVariables?: S;
outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : never;
However, unless the template for S
is explicitly set when implementing a RequestBatchRequest
, the Omit
on requestData
sees S
as never
, and type checking is lost. e.g.- in order for this to work, one would have to do something like:
const req: RequestBatchRequest<'someRequest', {fieldName: string}> = {
requestType: 'someRequest',
requestData: { aField: 'value' },
inputVariables: {fieldName: 'outputVariableName'},
}
If anyone has other ideas, I am all ears.
Description:
One of the many significant changes to the OBS websocket v5 protocol is that source visibility requires the source's ID within the scene where it is being enabled/disabled. For something as simple (and common) as toggling on/off a source, this is cumbersome and can add considerable complexity to client code. The "recommended" way of doing this is to use a batched request that get's a source's id within a scene (given the scene name and source name), store its value in the
outputVariables
field of that request, then send a source enable request that specifies aninputVariable
from the prior request'soutputVariables
as thesourceId
. (An example is given in the issue here: https://github.com/obsproject/obs-websocket/issues/1014#issuecomment-1319774798 ). Unfortunately, the typescript typedef forRequestBatchRequest
does not allow for theinputVariables
oroutputVariables
fields.Modifying the
type.d.ts
file to allow for an optionalinputVariables: any
andoutputVariables: any
allows this to work via obs-websocket-js. However it appears that this file is automatically generated from OBS Websocket's types?Versions Used (if applicable):