为什么TypeScript允许滥用String和字符串?

时间:2017-09-20 15:40:37

标签: typescript

为什么TypeScript允许我将字符串原语分配给类型为String的变量(对象类型)?例如,为什么这不会导致错误:

var str : String = '2333';

请注意,另一种方式不起作用:

var str : string = new String('2333'); // Error: Type 'String' is not assignable to type 'string'. 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.

代码如下:

const str: string = '2333'
console.log(`typeof str === "string" is ${typeof str === "string"}`)

const str2: String = new String('2333')
console.log(`str2 instanceof String is ${str2 instanceof String}`)
console.log(`typeof str2 === "string" is ${typeof str2 === "string"}`)

const str3: String = '2333'
console.log(`str3 instanceof String is ${str3 instanceof String}`)
console.log(`typeof str3 === "string" is ${typeof str3 === "string"}`)

它表示:

typeof str === "string" is true
str2 instanceof String is true
typeof str2 === "string" is false
str3 instanceof String is false
typeof str3 === "string" is true
来自strstr2

我们可以知道string是来自String的不同类型。为什么str3允许滥用两种类型?

1 个答案:

答案 0 :(得分:1)

简短版本:TypeScript专门允许将string分配给String

长版本:TypeScript允许将字符串,数字或布尔基元分配给其关联对象类型的变量。这在规范的§3.11.4§3.11.1部分中定义。

§3.11.4说:

  

S可分配给类型T,如果S没有相对于T(3.11.5)的多余属性并且以下之一为真,则可从S分配T:

     
      
  • S是对象类型,交集类型,枚举类型或Number,Boolean或String基元类型,T是对象类型,对于T中的每个成员M,以下之一为真:      
        
    • M是属性,S具有表观属性N      
          
      • M和N具有相同的名称,
      •   
      • N的类型可分配给M,
      •   
      • 如果M是必需属性,则N也是必需属性,
      •   
      • M和N都是公共的,M和N都是私有的,并且起源于同一个声明,M和N都受到保护并且起源于同一个声明,或者M受到保护,N被声明在派生自声明M的类。
      •   
    •   
    • M是可选属性,S没有与M同名的明显属性。
    •   
    • M是一个非专用的调用或构造签名,S有一个明显的调用或构造签名N,当M和N使用类型Any实例化为M和N声明的所有类型参数的类型参数时(如果有的话) )      
          
      • 签名属于同一类型(调用或构造),
      •   
      • M有一个rest参数或N中非可选参数的数量小于或等于M中的参数总数,
      •   
      • 对于两个签名中都存在的参数位置,N中的每个参数类型都可以分配给M中的相应参数类型,或者
      •   
      • M的结果类型为Void,或者N的结果类型可分配给M的结果类型。
      •   
    •   
    • M是U类型的字符串索引签名,U是Any类型,或者S具有可分配给U的类型的明显字符串索引签名。
    •   
    • M是U类型的数字索引签名,U是Any类型,或者S具有可分配给U的类型的明显字符串或数字索引签名。
    •   
  •   

然后§3.11.1说:

  

基本类型String的明显成员和所有字符串文字类型是全局接口类型“String”的明显成员。

拉出相关部分:

  

S (在我们的情况下为string可分配给类型T (在我们的例子中为String ...如果S有没有多余的属性相对于T,...... S是...数字,布尔或字符串基元类型,T是对象类型...并且对于T中的每个成员M ... M是属性和S具有明显的属性N,其中...... M和N具有相同的名称; N的类型可赋予M的类型;如果M是必需的财产,N也是必需的财产;而且M和N都是公开的......

...因为string的明显成员是String明显的成员。

§3.11的其他部分和其他各个部分(例如§3.2.3)也触及基本类型与其关联对象类型之间的关系。