TypeScript 项目实战

在 React 项目中使用 TypeScript

1. 在项目里安装 TypeScript 编译器,并在工程根目录运行 tsc –init,自动产生tsconfig.json文件。初始化得到的 tsconfig.json,增加”allowJs”: true,”jsx”: “react” 选项,antd 3 以前的版本需要在 tsconfig.json 的 compilerOptions 中配置 “allowSyntheticDefaultImports”: true。详细配置参考TypeScript 官方文档。tips: npm 安装不成功或者超级慢时建议使用镜像

npm install --save-dev typescript
tsc --init

2. 增加react声明文件,react 和 react 的声明文件的版本需一致

npm install --save-dev @types/react @types/react-dom @types/react-redux

3. 增加 ts 的loader,可参考Webpack & Typescript,如 awesome-typescript-loader。同时添加 resolve.extensions 来告诉 webpack 在解析查找 TypeScript 模块时该检索哪些文件扩展名。

npm install --save-dev awesome-typescript-loader

webpack 配置

module: {
   rules: [
    {
      test: /\.(ts|tsx)$/,
      exclude: /node_modules/,
      loader: "awesome-typescript-loader",
    }
   ]
 },
 resolve: {
   extensions: [".tsx", ".ts", ".js",".jsx"]
 }

4. 新项目可以参考 TypeScript-React-Starter

error fix

1. 找不到引入的 less 文件

写声明文件或者安装插件 typings-for-css-modules-loader

npm install --save-dev typings-for-css-modules-loader

webpack 配置,将css-loader 换成 typings-for-css-modules-loader ,保持原来的配置不变, loader 将会生成声明 less 的文件,使用 Webpack 的 WatchIgnorePlugin 插件配置来忽略它们

module: {
  rules: [
     {
        test: /\.less$/,
        use: [
          "style-loader",
          {
            loader: 'typings-for-css-modules-loader',
            options: {
              modules: true,
              namedExport: true,
              camelCase:true,
            }
          },
          // {
          //   loader: "css-loader",
          //   query: {
          //     importLoader: 1,
          //     localIdentName: "[path]___[name]__[local]___[hash:base64:5]",
          //     modules: true
          //   }
          // },
          "postcss-loader",
          "less-loader"
        ]
      },
  ]
},
plugins: [
    new webpack.WatchIgnorePlugin([
      /css\.d\.ts$/
    ]),
    ...
  ]

bug:TS2307: Cannot find module ‘./styles.less’. 遇到这种情况时重启项目

2. ERROR in [at-loader] ./node_modules/_antd@2.13.11@antd/lib/table/Table.d.ts:117:27

TS2304: Cannot find name ‘PropertyKey’

解决方案:tsconfig.json 中配置 “lib”: [“es6”, “dom”], “moduleResolution”: “node”,

3. antd 2.8.1版本报错 : TS2416: Property ‘componentWillReceiveProps’ in type ‘Mention’ is not assign…

解决方案:2.13.11版本和3.2.3版本都没有这个错。。。最后只能升到3.2.3版本

4. error TS2605: JSX element type Xxx is not a constructor function for JSX elements

解决方案:compilerOptions 中配置 "allowSyntheticDefaultImports": true

antd 3 以前的版本 Row 、Col 等组件会出现这个错误

5. 版本问题,版本之间的差异会导致很多问题

需要卸载模块的可以用这条命令

rm -rf node_modules && npm cache clean && npm uninstall 

部分package.json 配置

react-router 用的是3.0.2 版本,安装 @types/react-route 后,找不到 history 下面的方法,还需要安装一个 history 模块

“dependencies”:{
   "react": "^15.5.0",
   "react-dom": "^16.0.3",
   "react-redux": "^5.0.4", 
   "react-router": "3.0.2" ,
   "history": "^3.3.0",  
}
"devDependencies": {
    "awesome-typescript-loader": "^3.5.0",
    "@types/node": "^8.0.50",
    "@types/react": "^15.6.6",
    "@types/react-dom": "^0.14.22",
    "@types/react-redux": "^4.4.36",
    "@types/react-router": "3.0.2" 
}

6. 项目启动之后的 error : react-hot-loader.development.js:95 React-hot-loader

  • 查看一下 package.json 文件中 react-hot-loader 的版本是 next,我执行了 npm install ,react-hot-loader 也会安装,版本就不对应了,建议改成固定版本号如 ^4.0.0
  • 关于 React Hot Loader 插件,使用 typescript 时 Babel 不是必须的,但是 React Hot Loader 需要它,在 Webpack 中添加 babel-loader ,此处参考 react-hot-loader
{
  test: /\.(ts|tsx)$/,
  exclude: /node_modules/,
  use: [
    {
      loader: 'babel-loader',
      options: {
      presets: [
            "es2015-ie",
            "stage-0",
            "react"
          ],
       plugins: ['react-hot-loader/babel'],
      },
    },
    'awesome-typescript-loader', 
  ],
}

同时需要修改 tsconfig.json的配置

{
  "module": "commonjs",
  "target": "es6"
}

7. 找不到使用绝对路径的模块

解决方案: 在 tsconfig.json 里面设置路径解析,如 {“baseUrl”: “./app”, },baseUrl的值不会对相对文件的引入产生影响,moduleResolution标记(node, classic)指定使用哪种模块解析策略,参考模块解析

8. antd Form 组件的用法

import { Form } from 'antd';
import { FormComponentProps } from 'antd/lib/form';

interface UserFormProps extends FormComponentProps {
  age: number;
  name: string;
}

class UserForm extends React.Component<UserFormProps, any> {

}

9. TS2339: Property ‘xxx’ does not exist on type ‘IntrinsicAttributes & IntrinsicClassAttributes<Component<Pick<any, never>, ComponentState>> & Rea…’.

解决方案:在组件中声明 props

constructor(props:QueryProps){
    super(props)
 }

10. TS2339: Property ‘xxx’ does not exist on type ‘any[]….

解决方案:

  • 在代码中有给函数参数赋值{} ,ts会推导node类型就是{},里面无属性
createJobDir = (node={}) => {
   ...node.id...//   }

 //改成 interface Node {
  id:string;
}

createJobDir = (node:Node) => {
   ...node.id...//  }
  • 函数返回值的推断,ts 根据返回值推断出 {} 类型找不到 expandedKeys 属性报错
const searchRet  = getSearchTreeData(param1,param2)
    this.setState({
      expandedKeys: searchRet.expandedKeys
    })
//改成
    const searchRet:any  = getSearchTreeData(param1,param2)

附上 tsconfig.json 的配置

{
 "compilerOptions":{
     "target": "es6",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
     "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
     "lib": ["es6", "dom"],                             /* Specify library files to be included in the compilation:  */
     "allowJs": true,                       /* Allow javascript files to be compiled. */
     "jsx": "react",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
     "sourceMap": true,                     /* Generates corresponding '.map' file. */
     "outDir": "./dist/",                        /* Redirect output structure to the directory. */
     "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
     "baseUrl": "./app",                       /* Base directory to resolve non-absolute module names. */
     "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
     "experimentalDecorators": true        /* Enables experimental support for ES7 decorators. */
 }
  "exclude": [
    "node_modules",
    "build",
    "scripts",
    "pkgcmd",
    "server",
    "docs",
    "internals",
    "vendors"
  ]
}

未完待更。。。

    原文作者:谢小芹
    原文地址: https://zhuanlan.zhihu.com/p/34285874
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞