我正在尝试使用--strict
上的tsc
选项,但我遇到了以下“奇怪”的案例,我似乎并不理解。
如果我写:
function testStrict(input: {query?: {[prop: string]: string}}) {
if (input.query) {
Object.keys(input.query).forEach(key => {
input.query[key];
})
}
return input;
}
编译器抱怨:
test.ts(5,9):错误TS2532:对象可能是“未定义”。
(违规行为input.query[key];
)
我不明白的是,我已经在函数if (input.query)
的第一行检查了未定义的if guard,所以为什么编译器认为它可能是未定义的?< /强>
我通过在对象访问之前添加另一个相同的防护来修复此问题,例如:
function testStrict(input: {query?: {[prop: string]: string}}) {
if (input.query) {
Object.keys(input.query).forEach(key => {
if (input.query) {
input.query[key];
}
})
}
return input;
}
但我不明白为什么还需要另外一行。
答案 0 :(得分:12)
因为对forEach
的第二次访问发生在另一个函数内,所以箭头函数传递给undefined
。流分析不会跨越函数边界,因此,由于您处于另一个函数中,因此需要再次进行测试。
双重测试的替代方法是使用局部变量,因为变量的类型在赋值时被锁定,并且不包括function testStrict(input: { query?: { [prop: string]: string } }) {
if (input.query) {
let query = input.query;
Object.keys(input.query).forEach(key => {
query[key];
})
}
return input;
}
类型:
public function getPrefixAttribute()
{
$str=$this->attributes['Subject_name'];
$exclude=array('And', 'of','in');
$ret = '';
foreach (explode(' ', $str) as $word)
{
if(in_array($word, $exclude))
{continue;}
else{
$ret .= strtoupper(substr($word,0,1));}
}
return $ret;
}