TypeScript-DOM-lib-generator icon indicating copy to clipboard operation
TypeScript-DOM-lib-generator copied to clipboard

Incorrect type declaration for Crypto.getRandomValues

Open microshine opened this issue 4 years ago • 2 comments

Bug Report

🔎 Search Terms

WebCrypto, Crypto, getRandomValues

🕗 Version & Regression Information

  • This changed in 4.4

Description

Here is W3C spec for Crypto interface.

[Exposed=(Window,Worker)]
interface Crypto {
  [SecureContext] readonly attribute SubtleCrypto subtle;
  ArrayBufferView getRandomValues(ArrayBufferView array);
};

array argument in getRandomValues is ArrayBufferView but TS uses wrong interface declaration

interface Crypto {
    readonly subtle: SubtleCrypto;
    getRandomValues<T extends ArrayBufferView | null>(array: T): T;
}

Here is Google Chrome exception on getRandomValues usage with an empty argument image

microshine avatar Oct 26 '21 08:10 microshine

I'm trying to build a library that runs in both, browsers and servers and thus accepts either webcrypto or Crypto, but because the typings in lib.dom.ts accept null, it fails:

import { webcrypto } from "crypto";

type CryptoType = Crypto | typeof webcrypto;

function getRandomValues(crypto: CryptoType) {
    // @ts-expect-error `Crypto.getRandomValues` in `lib.dom.ts` is incorrectly typed: https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1194
    return crypto.getRandomValues(new Uint8Array());
}

getRandomValues(globalThis.crypto);
getRandomValues(webcrypto);

https://www.typescriptlang.org/play?target=9#code/JYWwDg9gTgLgBAbzgdwKYCMDGUCeYYRwC+cAZlBCHAETZ4HUDcAUMzHqnAMK74QAqHOAF5uvAnAA+cdmFQRSKDHT4tmpAK4A7TDGAQtcAOaoYAJQCGWgCaUAahYA2G1AGcAFCoIAuMfQEcAJSIzHBhcAD0EXAAAjCuALSoAB5yuklQFFBwAAY8-gB0JuZWtiAOzm45cMCGOY7A6AVlBfHVwK41OtBQqLqOODIc1r4AFjAwYK7eUUbAMKMaTZiUESDA2BCuCjARgnIAytjA+AkAIgDyALIJDegJJlqoUBYEUBEdri6uEQCMvwBOAAsoXCvRgGighi8ECKpksNnsTm+7ieyDgAFVajAABwAQUyFhw7kCgRYRFYxQRZQqKKMjgg6Cc-FGHQKMLJzCppSRlQ8aCw4ggnKAA

See also the w3c spec: https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues

Edit: Unfortunately it looks like just removing null is not enough. I tried editing to lib.dom.d.ts file manually to see if that would fix the issue, but got another error:

Argument of type 'import("crypto").webcrypto.Crypto' is not assignable to parameter of type 'Crypto'.
  Types of property 'getRandomValues' are incompatible.
    Type '<T extends Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | BigUint64Array | BigInt64Array>(typedArray: T) => T' is not assignable to type '<T extends ArrayBufferView>(array: T) => T'.
      Types of parameters 'typedArray' and 'array' are incompatible.
        Type 'T' is not assignable to type 'Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | BigUint64Array | BigInt64Array'.
          Type 'ArrayBufferView' is not assignable to type 'Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | BigUint64Array | BigInt64Array'.
            Type 'ArrayBufferView' is not assignable to type 'BigInt64Array'.
              Type 'T' is not assignable to type 'BigInt64Array'.
                Type 'ArrayBufferView' is missing the following properties from type 'BigInt64Array': BYTES_PER_ELEMENT, copyWithin, entries, every, and 24 more.ts(2345)

ZauberNerd avatar Feb 22 '23 14:02 ZauberNerd