ts中大小写类型的区别
前言
最开始的时候写ts的时候遇到过这种问题,为什么String
类型不能赋值给string
类型,他们不都是字符串吗?在js中不是万物皆对象吗?同类型为什么不可以?
const a: string = "a";
const b: String = a;
const c: string = b;
可以看到string
类型可以赋值给String
,而String
类型不能赋值给string
。
解惑
在JavaScript中,String
、Number
这种被称为包装器,你可以理解为他是一个类或者是构造函数,它返回的是一个对象,而string
是一个字面量,被称为原始数据类型。
原始数据类型(Primitive data types)有以下:
类型 | 例子 | 描述 |
---|---|---|
number | 1, -33, 2.5 | 任意数字 |
string | ‘hi’, “hi”, hi | 任意字符串 |
boolean | true、false | 布尔值true或false |
null | null | 值只能为null |
undefined | undefined | 值只能为undefined |
字面量 | 1,“1”,“hi” | 限制变量的值就是该字面量的值 |
any | * | 任意类型 |
unknown | * | 类型安全的any,unknown类型的变量不能直接赋值给其他变量。只能赋值给 any 类型和unknown类型。 |
void | 空值(undefined) | 没有值(或undefined) |
never | 没有值 | 不能是任何值 |
object | {name:‘孙悟空’} | 任意的JS对象 |
array | [1,2,3] | 任意JS数组 |
tuple | [4,5] | 元组,TS新增类型,固定长度数组 |
enum | enum{A, B} | 枚举,TS中新增类型 |
机翻佬会将原始数据类型Primitives
翻译成:基元类型。
而以大写字母开头的,被称为对象数据类型。
常见的对象数据类型(Object data types)如下:
类型 | 例子 | 描述 |
---|---|---|
Object | let obj: Object = {} | 最基础的对象类型,几乎所有的JavaScript对象都是Object类型 |
Array | let arr: Array<number> = [1, 2, 3] | 表示一个元素类型固定的数组 |
Date | let date: Date = new Date() | 代表日期 |
RegExp | let reg: RegExp = /^abc$/ | 代表一个正则表达式 |
Promise | let prom: Promise<any> = Promise.resolve() | 代表一个处理异步操作的对象 |
Map | let map: Map<number, string> = new Map() | 含有键和值对的集合 |
Set | let set: Set<number> = new Set() | 含有互不重复的值的集合 |
Function | let func: Function = () => {} | 表示一个函数 |
Class | class MyClass { } let cls: MyClass = new MyClass() | 表示一个类,是自定义对象类型的一个重要方式 |
Interface | interface IMyInterface { a: number } let inter: IMyInterface = { a: 1 } | 不是真正的对象, 但在TypeScript中常常被当作类型来使用,作为对象形状的描述 |
此时我们可能还是不清楚他们之间的区别,下面来写个例子:
const a: string = "a";
a.xxx = "xxx"; // Uncaught TypeError: Cannot create property 'xxx' on string 'a'
const b: String = new String("b");
b.xxx = "xxx";
console.log(b.xxx); // "xxx"
例子说明string是一个字面量值类型,它不像String类型,是一个对象,因为只有对象我们才可以自定义属性,而字面量不可以。
至于为什么我们可以调用字符对象的方法:
const a: string = "a";
console.log(a.length); // 1
是因为js会做隐式转换,将"a"
转为String对象,然后调用length,调用结束后又将对象变回"a"
。
这系列操作被称为:装箱和拆箱,正因为这个操作,小写的string可以赋值给大写的String,反之却不可以,因为String对象的原始值必须通过String.toString()
方法获取(不同对象获取方法不同,如:xxx.valueOf()
)。
而且这个例子也证明,在js中并不是万物皆对象。
此时你应该就可以明白小写类型和大写类型的区别了。
在ts中官方推荐是使用小写类型,大写是特殊情况,如无必要,不要使用。
特殊的object和Object
小写的object是除了number
,string
,boolean
,symbol
,null
或undefined
之外的类型,是更加具体的值,而大写的Object在JavaScript中是所有对象的基类,它可接受的类型就会比小写的object更广一些。
const a: object = "a";
const b: Object = "a";
可以看到string类型无法赋值给object,但是可以赋值给Object类型,因为装箱操作,字符串被转换为String对象,而Object又是它的基类,那么自然可以赋值给Object了。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
全部评论 3
lzan13
Google Chrome Windows 10Dabenshi
Google Chrome Windows 10木灵鱼儿
FireFox Windows 10