如何检查 Typescript 编译问题?
How to lint for Typescript compilation issues?
采用以下 Typescript 箭头函数:
/**
* Returns a probably unique component name.
*
* @param baseName a suggested name to make unique.
* @returns a probably unique name.
*/
export const getUniqueComponentName = (
baseName
): string => {
return baseName + Math.round(Math.random() * 10000000)
}
当 Typescript 在 tsconfig.json
中这样配置时:
"noImplicitAny": true,
这会正确地导致编译错误:
[ts] Parameter 'baseName' implicitly has an 'any' type.
Visual Studio代码也足够聪明,可以在开发过程中通知您这个问题。
我的目标是创建一个预提交 git 挂钩,以防止此类错误最终出现在版本控制中。我尝试用 tslint
、husky
和 lint-staged
使用 npm script
:
"lint": "tslint --project tsconfig.json --config tslint.json"
但是,这不会导致 tslint 显示编译错误。它被默默地忽略了。
然后我尝试在 tslint.json 中添加一条规则:
"typedef": [
true,
"arrow-parameter"
]
虽然这确实让 tslint 抱怨,但它也开始在匿名箭头函数中抱怨,而 tsc
编译器不会抱怨。在这些箭头函数中,没有必要添加类型,因为这些类型之前已经在父作用域中设置(它们是推断的)。
基本上,在这种情况下,我希望 tslint 的行为与 tsc 相同。任何时候有一个错误会导致编译失败(比如上面的箭头函数),我想阻止提交,但实际上并没有编译到Javascript。这可能吗?
我认为你最好的选择是 运行 tsc --noEmit -p .
并过滤修改文件中错误的输出。例如,我将以下脚本保存到 tsc-some-files
:
#!/bin/bash
declare -A include_files
for f in "$@"; do
include_files["${f#$PWD/}"]=1
done
node_modules/.bin/tsc --noEmit -p . | (
status=0
show_continuation=false
while IFS='' read -r line; do
case "$line" in
(' '*)
if $show_continuation; then
echo "$line" >&2
fi
;;
(*)
file="${line%%(*}"
if [ -n "${include_files["$file"]}" ]; then
show_continuation=true
echo "$line" >&2
status=1
else
show_continuation=false
fi
;;
esac
done
exit $status
)
并将 ./tsc-some-files
设置为我的 lint-staged
命令,它似乎起作用了。 (如果需要,用 bash 以外的编程语言编写此代码,留作 reader 的练习。)
请记住,编辑一个文件可能会在另一个文件中引入错误(例如,如果您更改了另一个文件正在使用的内容的类型),所以我敦促您清理您的项目通过任何必要的 hack 尽快出现 TypeScript 错误(只要你标记它们以便稍后搜索它们),然后将你的钩子设置为要求整个项目中没有错误。事实上,特别是关于 noImplicitAny
,当我几年前将一个 JavaScript 项目迁移到 TypeScript 时,我编写了一个脚本,在任何有隐式 [=] 的地方插入一个显式 any
16=] 错误,然后我在闲暇时修复了明确的 any
s。如果您有兴趣,我可以分享脚本。
我没有足够的声誉将此添加为评论,但任何人都会收到类似于
的错误
./scripts/ts-staged-files.sh: line 4:
src/ui/Components/Select/Select.tsx: division by 0
(error token is "/Components/Select/Select.tsx")
我对 Matt McCutchen 的回答做了这个小修改以修复它。
#!/bin/bash
include_files=()
for f in "$@"; do
include_files+=("${f#$PWD/}")
done
采用以下 Typescript 箭头函数:
/**
* Returns a probably unique component name.
*
* @param baseName a suggested name to make unique.
* @returns a probably unique name.
*/
export const getUniqueComponentName = (
baseName
): string => {
return baseName + Math.round(Math.random() * 10000000)
}
当 Typescript 在 tsconfig.json
中这样配置时:
"noImplicitAny": true,
这会正确地导致编译错误:
[ts] Parameter 'baseName' implicitly has an 'any' type.
Visual Studio代码也足够聪明,可以在开发过程中通知您这个问题。
我的目标是创建一个预提交 git 挂钩,以防止此类错误最终出现在版本控制中。我尝试用 tslint
、husky
和 lint-staged
使用 npm script
:
"lint": "tslint --project tsconfig.json --config tslint.json"
但是,这不会导致 tslint 显示编译错误。它被默默地忽略了。
然后我尝试在 tslint.json 中添加一条规则:
"typedef": [
true,
"arrow-parameter"
]
虽然这确实让 tslint 抱怨,但它也开始在匿名箭头函数中抱怨,而 tsc
编译器不会抱怨。在这些箭头函数中,没有必要添加类型,因为这些类型之前已经在父作用域中设置(它们是推断的)。
基本上,在这种情况下,我希望 tslint 的行为与 tsc 相同。任何时候有一个错误会导致编译失败(比如上面的箭头函数),我想阻止提交,但实际上并没有编译到Javascript。这可能吗?
我认为你最好的选择是 运行 tsc --noEmit -p .
并过滤修改文件中错误的输出。例如,我将以下脚本保存到 tsc-some-files
:
#!/bin/bash
declare -A include_files
for f in "$@"; do
include_files["${f#$PWD/}"]=1
done
node_modules/.bin/tsc --noEmit -p . | (
status=0
show_continuation=false
while IFS='' read -r line; do
case "$line" in
(' '*)
if $show_continuation; then
echo "$line" >&2
fi
;;
(*)
file="${line%%(*}"
if [ -n "${include_files["$file"]}" ]; then
show_continuation=true
echo "$line" >&2
status=1
else
show_continuation=false
fi
;;
esac
done
exit $status
)
并将 ./tsc-some-files
设置为我的 lint-staged
命令,它似乎起作用了。 (如果需要,用 bash 以外的编程语言编写此代码,留作 reader 的练习。)
请记住,编辑一个文件可能会在另一个文件中引入错误(例如,如果您更改了另一个文件正在使用的内容的类型),所以我敦促您清理您的项目通过任何必要的 hack 尽快出现 TypeScript 错误(只要你标记它们以便稍后搜索它们),然后将你的钩子设置为要求整个项目中没有错误。事实上,特别是关于 noImplicitAny
,当我几年前将一个 JavaScript 项目迁移到 TypeScript 时,我编写了一个脚本,在任何有隐式 [=] 的地方插入一个显式 any
16=] 错误,然后我在闲暇时修复了明确的 any
s。如果您有兴趣,我可以分享脚本。
我没有足够的声誉将此添加为评论,但任何人都会收到类似于
的错误./scripts/ts-staged-files.sh: line 4:
src/ui/Components/Select/Select.tsx: division by 0
(error token is "/Components/Select/Select.tsx")
我对 Matt McCutchen 的回答做了这个小修改以修复它。
#!/bin/bash
include_files=()
for f in "$@"; do
include_files+=("${f#$PWD/}")
done