美文网首页JavaScript技术前端大杂烩
JavaScript 和 TypeScript 中的布尔值

JavaScript 和 TypeScript 中的布尔值

作者: lio_zero | 来源:发表于2022-03-15 15:35 被阅读0次

    这几天整理的一下过往的文章和笔记,备份到了 Github 上,地址👉 blog

    如果我的内容帮助到了您,欢迎点个 Star 🎉🎉🎉 鼓励鼓励 :) ~~ 👆


    boolean 是 JavaScript 中一种原始数据类型。在 TypeScript 中,它总共允许四个值(?)。

    JavaScript 中的布尔值

    boolean 可以取 truefalse 的值。其他类型的值可以是 truthy 或 falsy,例如 undefinednull

    let b = true
    if(b) console.log('logged')
    
    b = false
    if(b) console.log('not logged')
    
    b = undefined
    if(b) console.log('not logged')
    
    b = null
    if(b) console.log('not logged')
    

    除了 undefinednullfalse 被认为是 falsy,""(空字符串,包括单引号和反引号)、-00,以及NaN 也为 falsy。

    要获取任意值的布尔值,可以使用 Boolean 函数:

    Boolean(false) // false
    Boolean(true) // true
    Boolean('false') // true
    Boolean("Hello World") // true
    Boolean({}) // true
    Boolean([]) // true
    Boolean(123.4) // true
    Boolean(Symbol()) // true
    Boolean(function() {}) // true
    Boolean(undefined) // false
    Boolean(null) // false
    Boolean(NaN) // false
    Boolean(0) // false
    Boolean("") // false
    

    有一个便捷的技巧:使用 !!,它与 Boolean 具有一样的效果。您可以尝试一下。

    所有空值的计算结果为 false。空对象 {} 和空数组 [](它本身就是一个对象)确实有值,因为它们是其他值的容器。

    Boolean 函数非常适合从集合中过滤空值:

    const collection = [
      { name: 'D.O', age: 20 },
      undefined,
      { name: 'D.', age: 30 },
      false,
      { name: 'C.', age: 2 },
      false
    ]
    
    collection.filter(Boolean)
    

    如果加上 Number,它将所有的值转换成对应的 numberNaN,这是一个非常酷的方式来快速获得实际值:

    const x = ['1.23', 2137123, 'D.O', false, 'O.O', undefined, null]
    
    x.map(Number).filter(Boolean) // [1.23, 2137123]
    

    Boolean 作为构造函数的形式存在,其转换规则与 Boolean 函数相同。但是,使用 new Boolean(...) 创建一个包装对象,它的值比较为 true,但引用比较 false

    const value = Boolean('Stefan') // true
    const reference = new Boolean('Stefan') // [Boolean: true]
    
    value == reference // true
    value === reference // false
    

    您可以通过 valueOf() 获得值,在进行比较:

    value === reference.valueOf() // true
    

    TypeScript 中的布尔值

    在 TypeScript 中,boolean 是一种原始类型。请务必使用小写版本,不要引用 Boolean 中的对象实例

    // bad
    const boolObject: Boolean = false
    
    // good
    const boolLiteral: boolean = false
    

    这是可行的,但这是一种糟糕的做法,因为我们几乎不需要 new Boolean 对象。

    您可以在 TypeScript 中将 truefalseundefinednull 分配给 boolean,而无需进行严格的 null 检查。

    const boolTrue: boolean = true // ✅
    const boolFalse: boolean = false // ✅
    const boolUndefined: boolean = undefined // ✅
    const boolNull: boolean = null // ✅
    

    因此,boolean 是我们唯一可以通过联合类型完全表达的:

    type MyBoolean = true | false | null | undefined // 与布尔值相同
    
    const mybool: MyBoolean = true
    const yourbool: boolean = false
    

    当启用 strictNullChecks 编译器标志时,值将减少为 truefalse

    const boolTrue: boolean = true // ✅
    const boolFalse: boolean = false // ✅
    const boolUndefined: boolean = undefined // ❌
    const boolNull: boolean = null // ❌
    

    所以我们的集合总共减少到两个值。

    type MyStrictBoolean = true | false
    

    我们还可以使用 NonNullable 帮助器类型去除空值:

    type NonNullable<T> = T extends null | undefined
      ? never
      : T
    
    type MyStrictBoolean = NonNullable<MyBoolean> // true | false
    

    boolean 由一组仅用于条件的有限值组成,这一事实允许有趣的条件类型。

    想象一下通过函数在数据存储中发生的变化。您在更新 userId 的函数中设置了一个标志。你必须提供 userId,然后:

    type CheckUserId<Properties, AddUserId> = 
      AddUserId extends true 
      ? Properties & { userId: string }
      : Properties & { userId?: string }
    

    根据通用 AddUserId 的值,我们希望属性 userId 被设置或者是可选的。

    通过从我们期望的类型扩展泛型,我们可以使这个类型更加明确

    - type CheckUserId<Properties, AddUserId> = 
    + type CheckuserId<
    +  Properties extends {},
    +  AddUserId extends boolean
    + >
         AddUserId extends true 
         ? Properties & { userId: string }
         : Properties & { userId?: string }
    

    在使用中,它可能会声明如下函数:

    declare function mutate<P, A extends boolean = false>
      (props: CheckUserId<P, A>, addUserId?: A): void
    

    请注意,我甚至为 A 设置了一个默认值,以确保 CheckUserId 根据要设置或不设置的 addUserId 提供正确的信息。

    实际作用:

    mutate({}) // ✅
    mutate({ data: 'Hello World' }) // ✅
    mutate({ name: 'O.O' }, false) // ✅
    mutate({ name: 'O.O' }, true) // ❌ userId 丢失
    mutate({ name: 'O.O', userId: 'ABCD' }, true) // ✅ userId is here
    

    如果您的代码很大程度上依赖于真值或假值,这将非常方便。

    相关文章

      网友评论

        本文标题:JavaScript 和 TypeScript 中的布尔值

        本文链接:https://www.haomeiwen.com/subject/jjtkdrtx.html