4

TypeScript's built-in typings are currently missing AbortSignal.timeout. How does one write a .d.ts file to add it?

This doesn't work:

declare namespace AbortSignal {
  function timeout(milliseconds: number): AbortSignal;
}
Duplicate identifier 'AbortSignal'.(2300)
lib.dom.d.ts(1984, 11): 'AbortSignal' was also declared here.
lib.dom.d.ts(1996, 13): and here.
Taymon
  • 24,950
  • 9
  • 62
  • 84
  • Probably [global augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation) is needed. – kelsny Sep 29 '22 at 22:44
  • The above code is already implicitly global because it's not in a module. If you do the same thing in a module and surround it with `declare global {}`, that doesn't help either. – Taymon Sep 29 '22 at 22:53
  • Something like that => https://stackoverflow.com/questions/46664732/typescript-how-to-add-static-methods-to-built-in-classes ? – Daniel Farina Sep 29 '22 at 23:09
  • That's the idea, but I don't see a straightforward way to do this with `AbortSignal`, because there is no type named `AbortSignalConstructor`. Instead, it's defined like this: https://github.com/microsoft/TypeScript/blob/v4.8.4/lib/lib.dom.d.ts#L1996-L2000 – Taymon Sep 29 '22 at 23:17
  • 1
    Did you try using the latest @types/web ? from: https://github.com/microsoft/TypeScript/issues/48003 looks like this is added – Derek Pollard Sep 29 '22 at 23:22
  • Aaaah, I think use can declare the AbortSignal again. But I can't figure out how the proper way to put new properties to it without override all the others. – Daniel Farina Sep 29 '22 at 23:24
  • @DerekPollard: Is it possible to do that without changing all the global typings throughout the entire monorepo codebase I'm working on? The latter sounds like it might be a large migration, if there are differences. – Taymon Sep 29 '22 at 23:35

2 Answers2

1

One way to get around this, is to simply redeclare the var again and include the timeout property:

declare var AbortSignal: {
  prototype: AbortSignal
  new(): AbortSignal
  abort(reason?: any): AbortSignal
  timeout(milliseconds: number): AbortSignal
}

This will only work if you also include all the properties that Typescript already knows about. An alternative workaround is to extend the type:

type AbortSignalWithTimeout = AbortSignal & { timeout(milliseconds: number): AbortSignal }

const timeoutSignal = (AbortSignal as unknown as AbortSignalWithTimeout).timeout(5000)
hverlind
  • 500
  • 1
  • 7
  • 14
0

If you are using TypeScript 4.5+, you can solve this by installing @types/web as a lib replacement:

pnpm add @typescript/lib-dom@npm:@types/web --save-dev
npm install @typescript/lib-dom@npm:@types/web --save-dev
yarn add @typescript/lib-dom@npm:@types/web --dev

This requires you to have "dom" in the lib-section of your tsconfig.json.

leonheess
  • 16,068
  • 14
  • 77
  • 112