在 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"
]
}
未完待更。。。