巧用ES系列4: TypeScript中的问号 ? 与感叹号 ! 是什么意思?
e2tox opened this issue · 21 comments
什么是 ?(问号)操作符?
在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');
祝大家编程愉快
good!
无意间听到这种用法:
person?.name?.firstName
可以理解成 person && person.name && person.firstName
nice
无意间听到这种用法:
person?.name?.firstName
可以理解成person && person.name && person.firstName
佛了
无意间听到这种用法:
person?.name?.firstName
可以理解成person && person.name && person.firstName
认真的么
初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!
我想转载到自己的博客,可以不?
无意间听到这种用法:
person?.name?.firstName
可以理解成person && person.name && person.firstName
认真的么
认真的,在试图访问的属性后面加上小问号就是 if not undefined 的逻辑
初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!
我想转载到自己的博客,可以不?
可以,随便使用 :)
无意间听到这种用法:
person?.name?.firstName
可以理解成person && person.name && person.firstName
认真的么
认真的,在试图访问的属性后面加上小问号就是 if not undefined 的逻辑
这个意思是对的,但是上面的式子有问题吧,应该是理解为person && person.name && person.name.firstName
其实感叹号还有种用法
let test: Object = null;
这样写会提示不能将null分配给Object
let test: Object = null!;
这样写了后就不会报错了
这个在cocos creator里面比较常用
还有个感叹号的用法
比如要赋值判断一个对象是否存在可以写成
let is_valid = (test)?true:false;
但是还有个更加简单的写法
let is_valid = !!test;
赞一个,在 TS 中认得,放在基于 TS 开发的 Vue 类组件中就不认得了,在网上翻了好久,hhh~
初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!
我想转载到自己的博客,可以不?
我也是,ant design pro 权限这一块看到的,一脸懵逼
好!
如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如
interface A {
name!: string,
age: number
}
会存在这种用法吗,如果存在的话
这和不加感叹号的区别呢
interface A {
name: string,
age: number
}
还是说感叹号在属性声明场景只能用于类的私有属性,而不能用于接口的类型声明
如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如
interface A { name!: string, age: number }会存在这种用法吗,如果存在的话
这和不加感叹号的区别呢
interface A { name: string, age: number }还是说感叹号在属性声明场景只能用于类的私有属性,而不能用于接口的类型声明
如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如
interface A { name!: string, age: number }会存在这种用法吗,如果存在的话
这和不加感叹号的区别呢
interface A { name: string, age: number }还是说感叹号在属性声明场景只能用于类的私有属性,而不能用于接口的类型声明
作者说了是强调 name 不为空值
赞一个,感谢🙏
说的很对
return new Error().stack?.split('\n');
这里问号的说法并不准确,在ts的语法树中,?和?.是不同的token,前者是QuestionToken, 而后者是QuestionDotToken,link
666
前端的语法、开发框架创新太快了,相似的工具一批一批的。