Open
Description
什么是 ?(问号)操作符?
在TypeScript里面,有3 4个地方会出现问号操作符,他们分别是
三元运算符
// 当 isNumber(input) 为 True 是返回 ? : 之间的部分; isNumber(input) 为 False 时
// 返回 : ; 之间的部分
const a = isNumber(input) ? input : String(input);
参数
// 这里的 ?表示这个参数 field 是一个可选参数
function getUser(user: string, field?: string) {
}
成员
// 这里的?表示这个name属性有可能不存在
class A {
name?: string
}
interface B {
name?: string
}
安全链式调用
// 这里 Error对象定义的stack是可选参数,如果这样写的话编译器会提示
// 出错 TS2532: Object is possibly 'undefined'.
return new Error().stack.split('\n');
// 我们可以添加?操作符,当stack属性存在时,调用 stack.split。若stack不存在,则返回空
return new Error().stack?.split('\n');
// 以上代码等同以下代码, 感谢 @dingyanhe 的监督
const err = new Error();
return err.stack && err.stack.split('\n');
什么是!(感叹号)操作符?
在TypeScript里面有3个地方会出现感叹号操作符,他们分别是
一元运算符
// ! 就是将之后的结果取反,比如:
// 当 isNumber(input) 为 True 时返回 False; isNumber(input) 为 False 时返回True
const a = !isNumber(input);
成员
// 因为接口B里面name被定义为可空的值,但是实际情况是不为空的,那么我们就可以
// 通过在class里面使用!,重新强调了name这个不为空值
class A implemented B {
name!: string
}
interface B {
name?: string
}
强制链式调用
// 这里 Error对象定义的stack是可选参数,如果这样写的话编译器会提示
// 出错 TS2532: Object is possibly 'undefined'.
new Error().stack.split('\n');
// 我们确信这个字段100%出现,那么就可以添加!,强调这个字段一定存在
new Error().stack!.split('\n');
祝大家编程愉快
Activity
[-]巧用ES系列4: TypeScript中的问号 '?' 与感叹号 '!' 操作符是什么意思?[/-][+]巧用ES系列4: TypeScript中的问号 ? 与感叹号 ! 是什么意思?[/+]heavenkiller2018 commentedon Jun 2, 2020
good!
dddddd889 commentedon Jul 6, 2020
无意间听到这种用法:
person?.name?.firstName
可以理解成person && person.name && person.firstName
Richar-Dada commentedon Jul 21, 2020
nice
GalaxySystem commentedon Aug 13, 2020
佛了
crecreek commentedon Nov 16, 2020
认真的么
Ansen commentedon Nov 23, 2020
初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!
我想转载到自己的博客,可以不?
lumixraku commentedon Dec 13, 2020
认真的,在试图访问的属性后面加上小问号就是 if not undefined 的逻辑
e2tox commentedon Dec 27, 2020
可以,随便使用 :)
fengnzl commentedon Jan 2, 2021
这个意思是对的,但是上面的式子有问题吧,应该是理解为
person && person.name && person.name.firstName
AveWei commentedon Feb 26, 2021
其实感叹号还有种用法
let test: Object = null;
这样写会提示不能将null分配给Object
let test: Object = null!;
这样写了后就不会报错了
这个在cocos creator里面比较常用
AveWei commentedon Feb 26, 2021
还有个感叹号的用法
比如要赋值判断一个对象是否存在可以写成
let is_valid = (test)?true:false;
但是还有个更加简单的写法
let is_valid = !!test;
hueralin commentedon May 11, 2021
赞一个,在 TS 中认得,放在基于 TS 开发的 Vue 类组件中就不认得了,在网上翻了好久,hhh~
Mustang-Galaxy commentedon Jun 24, 2021
我也是,ant design pro 权限这一块看到的,一脸懵逼
jacinyan commentedon Dec 31, 2021
好!
wilsonwangme commentedon Jan 19, 2022
如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如
会存在这种用法吗,如果存在的话
这和不加感叹号的区别呢
还是说感叹号在属性声明场景只能用于类的私有属性,而不能用于接口的类型声明
daydreamqun commentedon Mar 2, 2022
作者说了是强调 name 不为空值
daydreamqun commentedon Mar 2, 2022
赞一个,感谢🙏
dangdangdanglll commentedon May 14, 2022
说的很对
kylo5aby commentedon Aug 2, 2022
这里问号的说法并不准确,在ts的语法树中,?和?.是不同的token,前者是QuestionToken, 而后者是QuestionDotToken,link
GromLi commentedon Oct 9, 2022
666
LightCity commentedon Feb 21, 2023
前端的语法、开发框架创新太快了,相似的工具一批一批的。