router.get('/cells', async (req, res) => { try { const result = await fs.readFile(fullPath, { encoding: 'utf-8' }); res.send(JSON.parse(result)); } catch (err) { if (err.code === 'ENOENT') { // Object is of type 'unknown'.ts(2571) (local var) err: unknown await fs.writeFile(fullPath, '[]', 'utf-8'); res.send([]); } else { throw err; } }
err.code
hace este error ts: el Object is of type 'unknown'.ts(2571)
Definitivamente sé que existe err.code
, así que quiero saber cómo definir el tipo (o interfaz) de err
.
(información de la versión tsc: mi versión global de mecanografiado es v4.3.5 y el código anterior pertenece a mi proyecto que tiene mecanografiado v4.1.2 )
--- Editar ---
Finalmente sé por qué me sucede este error. Pensé que usé la versión tsc en 4.3.x, pero resultó que usé v4.4.x.
En vscode, cmd + shift + P
y busque la versión Select Typescript y en realidad usé v4.4.3, (pensé por error en la versión porque solo verifico la versión tsc desde la terminal)
Gracias por compartir el video de Youtube ,
En JavaScript/TypeScript puedes lanzar cualquier cosa, no solo errores. En teoría, podría ser cualquier cosa en el bloque catch. Si desea evitar el error de tipo, podría tener sentido verificar si el valor unknown
es un error del sistema antes de verificar el código.
if (err instanceof SystemError && err.code === 'ENOENT') { // file not found }
Recientemente, Typescript se actualizó para hacer que el objeto de error dentro de la catch
sea unknown
en lugar de any
lo que significa que su código se parece a esto para su compilador
catch(e: unknown) { // your logic }
Proporcione su propia interfaz y guárdela en otra variable para evitar este error:
catch(e : unknown) { const u = e as YourType // your logic }
Todavía puede usar any
allí, pero no se recomienda.
Como se indicó en otras respuestas, desde TypeScript 4.4, los errores se convierten automáticamente en desconocidos, por lo que no puede hacer nada con ellos sin verificar el tipo. Desafortunadamente, las isinstance
no se implementan como una clase importable, sino como un error normal con propiedades adicionales conectadas. este error exacto, por lo que verificar isinstance
contra Error
no le permitirá acceder a la propiedad err.code
. Dicho esto, puede hacer feliz al compilador con:
try { await fs.readFile(file); catch (err: NodeJS.ErrnoException) { if (err?.code === 'ENOENT') return; else throw err; }
La advertencia aquí es si simplemente haces if (err.code)...
y olvidas el ?
, el compilador no se quejará, pero es posible que obtenga un error de tiempo de ejecución. Esto es muy poco probable a menos que err sea nulo/indefinido, pero aún así no es perfectamente seguro, ya que podrías olvidar el ?
y obtener errores de tiempo de ejecución en teoría. El problema aquí es que le está diciendo al compilador que sabe cuál es el error cuando, de hecho, el error podría ser literalmente cualquier cosa (que es la motivación para convertir automáticamente los errores en desconocidos).
También puede hacer catch (err: any)
pero no obtendrá ninguna sugerencia de tipo para los códigos y aún está sujeto a los mismos problemas si olvida usar el acceso seguro en la propiedad del code
. No hay una forma particularmente fácil de evitar esto, ya que no puede simplemente usar un acceso seguro en tipos unknown
como este: if (err?.code === 'ENOENT') return;
. No estoy muy seguro de por qué y tal vez lo agreguen en una versión posterior, pero de cualquier manera, mi forma favorita de manejar estos errores fs es escribir una función auxiliar de typeguard como esta:
function isErrnoException(e: unknown): e is NodeJS.ErrnoException { if ('code' in (e as any)) return true; else return false; }
Y luego tu bloque catch como este:
try { await fs.readFile(file); } catch (err) { // writing err.code here after the typeguard call satisfies the compiler and is SAFE because we already checked the member exists in the guard function. if (isErrnoException(err) && err.code === 'ENOENT') return; else throw err; }
Esto comprueba que al menos el objeto de error es similar a ErrnoException en el sentido de que tiene una propiedad de code
. Puede ser más específico y probar que TODAS las propiedades de ErrnoException existen para asegurarse realmente de que se trata de una ErrnoException.
emita usando Record<string, unknown>
para el tipo que no conoce... por lo que será:
const mysteryObject = (unknownObject as Record<string, unknown>)
este mensaje a continuación realmente me ayudó y resolvió el problema también:
en mecanografiado puede agregar err: any ex:
runInitValidation(_bean: any, _oldVal: any, newVal: any) { const { validators } = this.props; if (!validators) return; try { for (let i = 0; i < validators.length; i++) { validators[i].validate(newVal); } } catch (err: any) { this.errorMessage = err.message; }
}