TypeScript: Vis en fejl, når en ekstern funktion returnerer en type af 'any'?
For eksempel returnerer funktionen JSON.parse(data) en type any. Så hvis du skriver noget som dette:
const parsed = JSON.parse('example');
console.log(parsed.somethingThatDoesntExist);
Der opstår ingen fejl i VSCode, på trods af at have noImplicitAny sat til true i min tsconfig.json, og min .eslintrc.js har reglen '@typescript-eslint/no-explicit-any': 'error'.
Jeg har også prøvet at tilføje følgende regler til min eslintrc.js, men de ser ud til at bryde al TypeScript-fejlkontrol:
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
I en ideel verden ville jeg ønske, at dette any blev antaget at være unknown, men en fejl ville også være fantastisk.
Her er min eslintrc.js:
module.exports = exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
ecmaVersion: 2021,
},
extends: ['plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'],
rules: {
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'prettier/prettier': [
'error',
{
trailingComma: 'all',
tabWidth: 2,
semi: true,
singleQuote: true,
bracketSpacing: true,
printWidth: 120,
endOfLine: 'auto',
},
],
},
};
og tsconfig.json:
{
"compilerOptions": {
"strict": true,
"target": "es6",
"module": "commonjs",
"lib": [
"es6",
"ES2021.String"
],
"esModuleInterop": true,
"moduleResolution": "node",
"outDir": "../build/",
"rootDir": ".",
"resolveJsonModule": true,
"composite": true,
"types": [],
"noImplicitAny": true,
"noImplicitThis": true,
"noImplicitReturns": true
}
}
Svar #1
Jeg tror, at din bedste mulighed ville være at overskrive alle biblioteker, hvor du ønsker en eksplicit type. Generelt er de indbyggede typer godt defineret (med undtagelse af JSON.parse), men dette kunne være nyttigt, hvis du vil rette en ødelagt eller stubbet type fra et eksternt bibliotek.
For globale (eller indbyggede) i en global.d.ts
declare global {
interface JSON {
parse<T>(text: string, reviver?: (this: any, key: string, value: any) => T): T
}
}
export {} //this is needed to make it a module
Eller en anden syntaks for moduler
declare module 'fooLibrary' {
declare function bar<T>(): T
}
// IE. require('fooLibrary') or import * from ('fooLibrary')
Og nu, når du prøver at bruge JSON.parse
const foo = JSON.parse('test');
// ^type? => unknown
const bar = JSON.parse<Record<string, any>>(...);
// ^type? => Record<string, any>
Se fungerende eksempel på TS Playground
Svar #2
Desværre kender jeg ikke til en compilerindstilling eller lignende global løsning, der giver det resultat, du ønsker. Du kan dog lave en assert-funktion, der forhindrer any på et bestemt udtryk:
type NotAny<T> = 0 extends 1 & T ? never : unknown
declare function assertNotAny<T extends NotAny<T>>(value: T): void
assertNotAny('"example"') // okay
assertNotAny(JSON.parse('"example"')) // error
Dette bruger det faktum, at any ikke kan tildeles til never. Ved at lave en betinget type, der bliver til never, kan du forårsage en typefejl, når any sendes ind.
For flere oplysninger, se https://stackoverflow.com/a/77385024/480608
