Skip to content

Commit 525ba2e

Browse files
committed
fix: importKey overload issue
TS is not able to select the proper overload. Giving it some help resolve the issue.
1 parent 20bb6e8 commit 525ba2e

File tree

1 file changed

+51
-32
lines changed

1 file changed

+51
-32
lines changed

modules/raw-rsa-keyring-browser/src/raw_rsa_keyring_web_crypto.ts

+51-32
Original file line numberDiff line numberDiff line change
@@ -191,50 +191,25 @@ export class RawRsaKeyringWebCrypto extends KeyringWebCrypto {
191191
static async importPublicKey(
192192
publicKey: RsaImportableKey
193193
): Promise<AwsEsdkJsCryptoKey> {
194-
const { wrappingAlgorithm, format, key } = getImportOptions(publicKey)
194+
const op = getImportOptions(publicKey)
195195
const backend = await getWebCryptoBackend()
196196
const subtle = getNonZeroByteBackend(backend)
197-
// @ts-ignore // see TS2769 Note below
198-
return subtle.importKey(format, key, wrappingAlgorithm, false, ['wrapKey'])
199-
}
200197

201-
// TS2769 Note:
202-
// TS2769 is "No overload matches this call".
203-
// Above and below, TS is incorrect.
204-
// `importKey` has two overrides,
205-
// They are abbreviated below:
206-
// ```
207-
// importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | ... , extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
208-
// importKey(format: "raw" | "pkcs8" | "spki", keyData: BufferSource, algorithm: AlgorithmIdentifier | ..., extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
209-
// ```
210-
// The method getImportOptions explicitly
211-
// returns format & key that match
212-
// these overrides.
213-
// However, TS is unable to recognize this.
198+
return ImportKeyTypeOverload(op, subtle, ['wrapKey'])
199+
}
214200

215201
static async importPrivateKey(
216202
privateKey: RsaImportableKey
217203
): Promise<AwsEsdkJsCryptoKey | MixedBackendCryptoKey> {
218-
const { format, key, wrappingAlgorithm } = getImportOptions(privateKey)
204+
const op = getImportOptions(privateKey)
219205
const backend = await getWebCryptoBackend()
220206

221207
if (isFullSupportWebCryptoBackend(backend)) {
222-
// prettier-ignore
223-
return backend.subtle.importKey(
224-
// @ts-ignore // see TS2769 Note above
225-
format, key, wrappingAlgorithm, false, ['unwrapKey']
226-
)
208+
return ImportKeyTypeOverload(op, backend.subtle, ['unwrapKey'])
227209
} else {
228-
// prettier-ignore
229210
return Promise.all([
230-
backend.nonZeroByteSubtle.importKey(
231-
// @ts-ignore // see TS2769 Note above
232-
format, key, wrappingAlgorithm, false, ['unwrapKey']
233-
),
234-
backend.zeroByteSubtle.importKey(
235-
// @ts-ignore // see TS2769 Note above
236-
format, key, wrappingAlgorithm, false, ['unwrapKey']
237-
),
211+
ImportKeyTypeOverload(op, backend.nonZeroByteSubtle, ['unwrapKey']),
212+
ImportKeyTypeOverload(op, backend.zeroByteSubtle, ['unwrapKey']),
238213
]).then(([nonZeroByteCryptoKey, zeroByteCryptoKey]) => ({
239214
nonZeroByteCryptoKey,
240215
zeroByteCryptoKey,
@@ -243,3 +218,47 @@ export class RawRsaKeyringWebCrypto extends KeyringWebCrypto {
243218
}
244219
}
245220
immutableClass(RawRsaKeyringWebCrypto)
221+
222+
// TS2769 Note:
223+
// TS2769 is "No overload matches this call".
224+
// Above and below, TS is incorrect.
225+
// `importKey` has two overrides,
226+
// They are abbreviated below:
227+
// ```
228+
// importKey(format: "jwk", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | ... , extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
229+
// importKey(format: "raw" | "pkcs8" | "spki", keyData: BufferSource, algorithm: AlgorithmIdentifier | ..., extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
230+
// ```
231+
// The method getImportOptions explicitly
232+
// returns format & key that match
233+
// these overrides.
234+
// However, TS is unable to recognize this easily.
235+
// The following ugly function does the disambiguation.
236+
// There are 2 problems that TS is having.
237+
// First when format key and wrappingAlgorithm are independent,
238+
// TS does not _remember_ the relationship between format and key.
239+
// The second issue is related,
240+
// when trying to select the proper overload,
241+
// it is collapsing the definition of format.
242+
// Thus discriminating the union by `format`
243+
// helps TS understand all the arguments.
244+
async function ImportKeyTypeOverload(
245+
op: ReturnType<typeof getImportOptions>,
246+
subtle: SubtleCrypto,
247+
keyUsages: KeyUsage[]
248+
): Promise<AwsEsdkJsCryptoKey> {
249+
return op.format == 'jwk'
250+
? subtle.importKey(
251+
op.format,
252+
op.key,
253+
op.wrappingAlgorithm,
254+
false,
255+
keyUsages
256+
)
257+
: subtle.importKey(
258+
op.format,
259+
op.key,
260+
op.wrappingAlgorithm,
261+
false,
262+
keyUsages
263+
)
264+
}

0 commit comments

Comments
 (0)