TypeScript:当外部函数返回“any”类型时显示错误?

问题描述 投票:0回答:2

例如,函数

JSON.parse(data)
返回
any
类型。所以如果你写这样的东西:

const parsed = JSON.parse('example');

console.log(parsed.somethingThatDoesntExist);

尽管我的

noImplicitAny
中的
true
设置为
tsconfig.json
,并且我的
.eslintrc.js
具有规则
'@typescript-eslint/no-explicit-any': 'error'
,但 VSCode 中没有出现错误。

我还尝试将以下规则添加到我的

eslintrc.js
中,但是它们似乎破坏了所有 TypeScript 错误检查:

'@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',

在理想的世界中,我希望这个

any
被假定为
unknown
,但错误也很大。

这是我的

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',
      },
    ],
  },
};

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
  }
}
typescript any
2个回答
1
投票

我认为最好的选择是覆盖任何需要显式类型的库。一般来说,内置函数的类型很好(JSON.parse 除外),但是如果您想修复外部库中损坏或存根的类型,这可能会很有帮助。

对于

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

或者模块的不同语法

declare module 'fooLibrary' {
  declare function bar<T>(): T
}
// IE. require('fooLibrary') or import * from ('fooLibrary')

现在当你尝试使用

JSON.parse

const foo = JSON.parse('test');
//   ^type? => unknown
const bar = JSON.parse<Record<string, any>>(...);
//   ^type? => Record<string, any>

在 TS Playground 上查看工作示例


0
投票

不幸的是,我不知道编译器选项或类似的全局解决方案可以提供您想要的结果。但是,您可以制作一个断言函数,不允许在特定表达式上使用

any

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

这利用了

any
不能分配给
never
这一事实。通过创建解析为
never
的条件类型,您可能会在传入
any
时导致类型错误。

有关更多详细信息,请参阅https://stackoverflow.com/a/77385024/480608

© www.soinside.com 2019 - 2024. All rights reserved.