Skip to content

巧用ES系列4: TypeScript中的问号 ? 与感叹号 ! 是什么意思? #9

Open
@e2tox

Description

@e2tox

什么是 ?(问号)操作符?

在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

changed the title [-]巧用ES系列4: TypeScript中的问号 '?' 与感叹号 '!' 操作符是什么意思?[/-] [+]巧用ES系列4: TypeScript中的问号 ? 与感叹号 ! 是什么意思?[/+] on Dec 12, 2018
heavenkiller2018

heavenkiller2018 commented on Jun 2, 2020

@heavenkiller2018

good!

dddddd889

dddddd889 commented on Jul 6, 2020

@dddddd889

无意间听到这种用法:

person?.name?.firstName 可以理解成 person && person.name && person.firstName

Richar-Dada

Richar-Dada commented on Jul 21, 2020

@Richar-Dada

nice

GalaxySystem

GalaxySystem commented on Aug 13, 2020

@GalaxySystem

无意间听到这种用法:

person?.name?.firstName 可以理解成 person && person.name && person.firstName

佛了

crecreek

crecreek commented on Nov 16, 2020

@crecreek

无意间听到这种用法:

person?.name?.firstName 可以理解成 person && person.name && person.firstName

认真的么

Ansen

Ansen commented on Nov 23, 2020

@Ansen

初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!

我想转载到自己的博客,可以不?

lumixraku

lumixraku commented on Dec 13, 2020

@lumixraku

无意间听到这种用法:
person?.name?.firstName 可以理解成 person && person.name && person.firstName

认真的么

认真的,在试图访问的属性后面加上小问号就是 if not undefined 的逻辑

e2tox

e2tox commented on Dec 27, 2020

@e2tox
OwnerAuthor

初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!

我想转载到自己的博客,可以不?

可以,随便使用 :)

fengnzl

fengnzl commented on Jan 2, 2021

@fengnzl

无意间听到这种用法:
person?.name?.firstName 可以理解成 person && person.name && person.firstName

认真的么

认真的,在试图访问的属性后面加上小问号就是 if not undefined 的逻辑

这个意思是对的,但是上面的式子有问题吧,应该是理解为person && person.name && person.name.firstName

AveWei

AveWei commented on Feb 26, 2021

@AveWei

其实感叹号还有种用法

let test: Object = null;
这样写会提示不能将null分配给Object

let test: Object = null!;
这样写了后就不会报错了

这个在cocos creator里面比较常用

AveWei

AveWei commented on Feb 26, 2021

@AveWei

还有个感叹号的用法
比如要赋值判断一个对象是否存在可以写成
let is_valid = (test)?true:false;
但是还有个更加简单的写法
let is_valid = !!test;

hueralin

hueralin commented on May 11, 2021

@hueralin

赞一个,在 TS 中认得,放在基于 TS 开发的 Vue 类组件中就不认得了,在网上翻了好久,hhh~

Mustang-Galaxy

Mustang-Galaxy commented on Jun 24, 2021

@Mustang-Galaxy

初学React 在 Ant Design Pro 中看到了这样的写法,谢谢解惑!

我想转载到自己的博客,可以不?

我也是,ant design pro 权限这一块看到的,一脸懵逼

jacinyan

jacinyan commented on Dec 31, 2021

@jacinyan

好!

wilsonwangme

wilsonwangme commented on Jan 19, 2022

@wilsonwangme

如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如

interface A {
    name!: string,
    age: number
}

会存在这种用法吗,如果存在的话

这和不加感叹号的区别呢

interface A {
    name: string,
    age: number
}

还是说感叹号在属性声明场景只能用于类的私有属性,而不能用于接口的类型声明

daydreamqun

daydreamqun commented on Mar 2, 2022

@daydreamqun

如果是接口声明属性中使用了感叹号,具体是什么作用呢,比如

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 不为空值

daydreamqun

daydreamqun commented on Mar 2, 2022

@daydreamqun

赞一个,感谢🙏

dangdangdanglll

dangdangdanglll commented on May 14, 2022

@dangdangdanglll

说的很对

kylo5aby

kylo5aby commented on Aug 2, 2022

@kylo5aby
return new Error().stack?.split('\n');

这里问号的说法并不准确,在ts的语法树中,?和?.是不同的token,前者是QuestionToken, 而后者是QuestionDotToken,link

GromLi

GromLi commented on Oct 9, 2022

@GromLi

666

LightCity

LightCity commented on Feb 21, 2023

@LightCity

前端的语法、开发框架创新太快了,相似的工具一批一批的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Ansen@e2tox@LightCity@lumixraku@Richar-Dada

        Issue actions

          巧用ES系列4: TypeScript中的问号 ? 与感叹号 ! 是什么意思? · Issue #9 · e2tox/blog