-
| (Somewhat related to #519.) Since the package exports the error types as: export * as errors from './util/errors.js'I can only really get a reference to an error as a value and not as a type. To use it as a type, I have to do something like: import * as jose from 'jose';
InstanceType<typeof jose.errors.JOSEError> // back to the type
// or...
import { errors } from 'jose';
const { JOSEError } = errors;
InstanceType<typeof JOSEError> // back to the typeI might want a reference to the class as a type to write generic code like this: // Combines the static members of `JOSEError` with its constructor.
type JoseErrorClass<E extends InstanceType<typeof JOSEError>> = typeof JOSEError & {
  new(...args: any[]): E,
}
function expectJoseError<E extends InstanceType<typeof JOSEError>>(error: Error | undefined, type: JoseErrorClass<E>): void {
  expectNotNil(error);
  expectInstanceOf(error, type);
  // This `code` check is technically unnecessary because of the `instanceof` check above,
  //   but it does expand the scope of the example a bit.
  expect(error.code).toBe(type.code);
}I could use that like this: expectJoseError(error, JWSSignatureVerificationFailed);All of this could be slightly simpler if the errors were exported in a way that allowed TypeScript to get them as types more easily. Maybe it's fine this way, though? Adding  Those  export function expectNotNil<T>(actual?: T): asserts actual is NonNullable<T> {
  expect(actual).not.toBeUndefined();
  expect(actual).not.toBeNull();
}
export function expectInstanceOf<T, A extends T>(actual: T, of: Newable<A>): asserts actual is A {
  expect(actual).toBeInstanceOf(of);
} | 
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 2 replies
-
| I admire your dedication to types ;) | 
Beta Was this translation helpful? Give feedback.
-
| Thanks, I think 😅. Actually getting to use TypeScript professionally in the last year or so has had its ups and downs. I get 🤩 when I see opportunities to write generic code, and having an expressive type system with generics just makes the star-eyes bigger, but it has arguably wasted a lot of time in many circumstances. I think TypeScript is probably a lot simpler when just consuming and not trying to produce broadly-reusable code. Anyway, I guess I never really asked a question. I suppose we could make a backwards-compatible change to the current export: Line 53 in 9bbe5fb By adding another export next to it. export * as errors from './util/errors.js'
export * from './util/errors.js'I think this would allow TS to import the errors as types, right? Because the import would look like: import { JOSEError } from 'jose'Though, if I were the maintainer, the idea of exporting the same module twice, differently, would probably bother me somewhat 😂. That said, I was much more distressed by the issue until I found out how to use  An alternative would be that I could write a small addition to the docs (somewhere around here, I guess: https://github.com/panva/jose/blob/main/docs/modules/util_errors.md) that talks about the types vs. values thing and how to use  @panva What do you think? | 
Beta Was this translation helpful? Give feedback.
-
| 
 Go for it. | 
Beta Was this translation helpful? Give feedback.
-
| In v5.1.3 you can to get around the root export being an object with values as keys import { JOSEError } from 'jose/errors' | 
Beta Was this translation helpful? Give feedback.
-
| Ooh, nice! Yeah, I didn't want to do a deep import before because it would've been something like: import { JOSEError } from 'jose/dist/node/esm/util/errors.js'😂 | 
Beta Was this translation helpful? Give feedback.
-
| Confirmed that this works! 🙌 | 
Beta Was this translation helpful? Give feedback.
In v5.1.3 you can to get around the root export being an object with values as keys