microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.58k stars 12.43k forks source link

AudioWorkletProcessor type definition is missing #28308

Open teali opened 5 years ago

teali commented 5 years ago

TypeScript Version: 3.2.0-dev.201xxxxx

Search Terms: AudioWorkletProcessor

You guys have type definitions for AudioWorkletNode and such but missed the definition for AudioWorkletProcessor as per: https://webaudio.github.io/web-audio-api/#audioworkletprocessor

This is what I have for now:

interface AudioWorkletProcessor {
    readonly port: MessagePort;
    process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Map<string, Float32Array>): void;
}

declare var AudioWorkletProcessor: {
    prototype: AudioWorkletProcessor;
    new(options?: AudioWorkletNodeOptions): AudioWorkletProcessor;
}

Cheers

weswigham commented 5 years ago

PRs welcomed. You can find more information about contributing lib.d.ts fixes at https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md#contributing-libdts-fixes.

saschanaz commented 5 years ago

AudioWorkletProcessor is a type only for AudioWorklet. Do we want to add dom.audioworklet.d.ts for this, or do we have to add all worklet types into dom.worker.d.ts?

Edit: types-web now supports audioworklet, so please try it if anyone needs it.

weswigham commented 5 years ago

@DanielRosenwasser you have a preference here?

navelpluisje commented 5 years ago

@teali It looks like the type of the parameters-parameter is not right. It should not be a Map. When typing it to a Map you need to use the get methode to get a value from the Map. In the specs they also are talking about a Map. But that has been clarified in the specs after I created a bug report for Chromium, because in Chromium the parameters-parameter is an Object.

Hongchan Choi (one of the authors of the spec) responded with the next comment:

The description says it is a "map", but it's actually an associative array, which is a JS object.

For a project I'm working on I added:

declare type AudioParamList = {
  [key: string]: Float32Array
}

This way typescript works great with the workletNode.

saschanaz commented 5 years ago

@navelpluisje parameters: Record<string, Float32Array> should also work.

navelpluisje commented 5 years ago

Wasn't aware of that one. Not using typescript for that long. Thanx

waterplea commented 4 years ago

Working on Web Audio API library I was surprised it's missing in TS. Most of other stuff, including other Audio Worklet related classes/interfaces are present.

joanrieu commented 4 years ago

Note that the return type of the process method should be boolean, not void.

The return value of this method controls the lifetime of the AudioWorkletProcessor's associated AudioWorkletNode.

See the docs for more details.

joanrieu commented 4 years ago

The definition of registerProcessor was missing as well.

I'm using the following definitions:

interface AudioWorkletProcessor {
  readonly port: MessagePort;
  process(
    inputs: Float32Array[][],
    outputs: Float32Array[][],
    parameters: Record<string, Float32Array>
  ): boolean;
}

declare var AudioWorkletProcessor: {
  prototype: AudioWorkletProcessor;
  new (options?: AudioWorkletNodeOptions): AudioWorkletProcessor;
};

declare function registerProcessor(
  name: string,
  processorCtor: (new (
    options?: AudioWorkletNodeOptions
  ) => AudioWorkletProcessor) & {
    parameterDescriptors?: AudioParamDescriptor[];
  }
);

EDIT: added the parameter descriptors to the registerProcessor() declaration.

drohen commented 3 years ago
declare function registerProcessor(
  name: string,
  processorCtor: (new (
    options?: AudioWorkletNodeOptions
  ) => AudioWorkletProcessor) & {
    parameterDescriptors?: AudioParamDescriptor[];
  }
): undefined;

Add correct return type to avoid implicit any warnings. https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletGlobalScope/registerProcessor#return_value

roddypratt commented 2 years ago

I think the typescript DOM lib generator publishes this to package @types/audioworklet but that needs to be manually added to your package.json

meditating-monkey commented 2 years ago

I've added @types/audioworklet to my package but when I create a custom processor that extends AudioWorkletProcessor in typescript. It shows an error regarding the process function because it isn't declared in the interface of the AudioWorkletProcessor. Upon hovering over AudioWorkletProcessor in VSCode, the following text is shown:

var AudioWorkletProcessor: {
    new (): AudioWorkletProcessor;
    prototype: AudioWorkletProcessor;
}

What's the problem here? Why hasn't the declarations (discussed above) been pushed to the @types/audioworklet package?

PS: Please forgive any ignorance with regards to type declarations and all from my side πŸ˜…

spicemix commented 2 years ago

I've added @types/audioworklet to my package but when I create a custom processor that extends AudioWorkletProcessor in typescript. It shows an error regarding the process function because it isn't declared in the interface of the AudioWorkletProcessor. Upon hovering over AudioWorkletProcessor in VSCode, the following text is shown:

var AudioWorkletProcessor: {
    new (): AudioWorkletProcessor;
    prototype: AudioWorkletProcessor;
}

What's the problem here? Why hasn't the declarations (discussed above) been pushed to the @types/audioworklet package?

PS: Please forgive any ignorance with regards to type declarations and all from my side πŸ˜…

I get an error because the optional options constructor parameter is missing entirely from that definition. It's present in the handwritten versions further up the thread. Surprising that was overlooked.

CongAn commented 1 year ago

Install @types/audioworklet

npm i @types/audioworklet -D

Add @ types/audioworklet to the tsconfig. json file to work for me.

{
  "compilerOptions": {
    "types": [
      "@types/audioworklet"
    ]
  }
}
formula1 commented 1 year ago

Install @types/audioworklet

npm i @types/audioworklet -D

Add @ types/audioworklet to the tsconfig. json file to work for me.

{
  "compilerOptions": {
    "types": [
      "@types/audioworklet"
    ]
  }
}

This did funky things with URL.createObjectURL (said it didn't exist) so I had to uninstall it and use


interface AudioWorkletProcessor {
 readonly port: MessagePort;
 process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record<string, Float32Array>): boolean;
}

declare var AudioWorkletProcessor: {
 prototype: AudioWorkletProcessor;
 new(options?: AudioWorkletNodeOptions): AudioWorkletProcessor;
}

type AudioParamDescriptor = {
  name: string,
  automationRate: "a-rate" | "k-rate"
  minValue: number,
  maxValue: number,
  defaultValue: number
}

declare function registerProcessor(
 name: string,
 processorCtor: (new (
   options?: AudioWorkletNodeOptions
 ) => AudioWorkletProcessor) & {
   parameterDescriptors?: AudioParamDescriptor[];
 }
):undefined;
saschanaz commented 1 year ago

What funky things did you have?

formula1 commented 1 year ago

@saschanaz I was using URL.createObjectURL but @types/audioworklet said that function didn't exist

saschanaz commented 1 year ago

Have you tried it again recently? It has been there since March 2022. https://github.com/microsoft/TypeScript-DOM-lib-generator/commit/d5fc0b161bd92c1052d9983194325e10e608e7f1, @types/audioworklet@0.0.24.

saschanaz commented 1 year ago

Oh wait, not just URL, but URL.createObjectURL. That's not funky, it indeed doesn't exist there per the spec and also in Firefox and Chrome.

Spec: https://w3c.github.io/FileAPI/#creating-revoking Firefox: https://searchfox.org/mozilla-central/rev/3c2ee8453be78da8210faa51195a486fc345ef2c/dom/webidl/URL.webidl#50 Chrome: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/mediasource/url_media_source.idl;l=36;drc=0aee4434a4dba42a42abaea9bfbc0cd196a63bc1

NuclearPhoenixx commented 9 months ago

I think the typescript DOM lib generator publishes this to package @types/audioworklet but that needs to be manually added to your package.json

Unfortunately, @types/audioworklet only works if you aren't using DOM at the same time because of definition conflicts.

majaha commented 8 months ago

I came up with this more up to date version of the types from what I could glean from here, here and here.

interface AudioWorkletProcessor {
    readonly port: MessagePort;
}

interface AudioWorkletProcessorImpl extends AudioWorkletProcessor {
    process(
        inputs: Float32Array[][],
        outputs: Float32Array[][],
        parameters: Record<string, Float32Array>
    ): boolean;
}

declare var AudioWorkletProcessor: {
    prototype: AudioWorkletProcessor;
    new (options?: AudioWorkletNodeOptions): AudioWorkletProcessor;
};

type AudioParamDescriptor = {
    name: string,
    automationRate: AutomationRate,
    minValue: number,
    maxValue: number,
    defaultValue: number
}

interface AudioWorkletProcessorConstructor {
    new (options?: AudioWorkletNodeOptions): AudioWorkletProcessorImpl;
    parameterDescriptors?: AudioParamDescriptor[];
}

declare function registerProcessor(
    name: string,
    processorCtor: AudioWorkletProcessorConstructor,
): void;

Some of these are only meant to be in a AudioWorkletGlobalScope, but this also puts them in other global scopes where they're not actually available, like the window scope. It seems to me that typescript needs better support for having multiple global scopes defined in the same project - either by configuration in tsconfig.js, or by marking up the files with /// directives. Or maybe it needs to move away from the concept of a global scope, and instead it needs to natively understand Global Objects.

It seems like the best way to do this that currently exists is Project References (also this Stack Overflow answer). But you shouldn't have to set up a whole sub-project just for one Web worker file - it should just work!

UrielCh commented 8 months ago

I tried @majaha typing after making a small change:

type AudioParamDescriptor = {
    name: string,
    automationRate?: AutomationRate,
    minValue?: number,
    maxValue?: number,
    defaultValue?: number
}

All attributes are optional except name.

In my case, it only works partially. I prefixed my worklet with: // @ts-check /// <reference types="./AudioWorklet.d.ts" />

but my process parameters type are still any

By the way, I also added the worklet global variables:

/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletGlobalScope/currentFrame) */
declare var currentFrame: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletGlobalScope/currentTime) */
declare var currentTime: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletGlobalScope/sampleRate) */
declare var sampleRate: number;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletGlobalScope/registerProcessor) */

Adding //// <reference types="npm:@types/audioworklet" /> does not work well in my VS Code deno plugin.