此类型的变量不⽀持使⽤花括号进⾏索引_TypeScript笔记
(四)类型字⾯量
4. 类型字⾯量
JavaScript 中的对象字⾯量
对象字⾯量 (Object literals)是 JavaScript 中的⼀个⽣成对象的功能。
对象字⾯值是封闭在花括号对({})中的⼀个对象的零个或多个"属性名-值"对的(元素)列表。
我们⽇常使⽤的是 ES 2015 开始引⼊的增强的对象字⾯量 (Enhanced Object literals)。
下⾯是⼀个例⼦:
const obj = {
0x1: 'foo',
bar: 114514,
"baz": [1, 2, {}],
// __proto_
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + String();
},
// Property of arrow function
arrowFunctionProperty: () => 'arrowFunctionProperty',
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42,
// Computed property names of Symbol
[Symbol.iterator]: '123',
};
我就不赘述语法了。就简单提⼀下,key 是 0x1 还是 0b1 还是 1,都相当于是 "1"。
key 可以是标识符(bar,arrowFunctionProperty, handler),字符串("baz"),数字(0x1),⽅括号括起来的计算出的值。Symbol 只可以放在⽅括号中括起来。
类型字⾯量
请注意⼀下,这⾥是说类型字⾯量(Type Literal),不是说字⾯量类型(Literal Type),这个名词的出处是 TypeScript 的源码,⽂档和很多教程⾥貌似都没有提这个名词,除了我在 tslint 中看到的这条规则。
毕竟本⽂本质上就是⽂档的搬运⼯,所以我提⼀下,在 TypeScript 中对应的⽂档是 Type Alias。⽂档中⽤ object literal type 来表⽰ type literal。
与类型字⾯量对应的就是 js 中的对象字⾯量。所以他们的语法很相似。
type Handler = Function;
type Foo = {
baz: [
1,
number,
{
y: Array<string>;
}
]
;
readonly handler: Handler;
toString(): string;
readonly [Symbol.iterator]: '123';
0x1: 'foo';
"bar": number;
};
我们可以把⼀对键值对叫做 Signature,⼀个 type literal 由花括号和 signature 列表组成,上⾯的例⼦中实际上由两种 signature: ⼀种是 toString 这种,叫做 method signature,与 js 中的 object literal 中的 method。它不能设 readonly 作为 modifier,它只能是可读可写的。 上⾯例⼦中,其余的都是 property signature,property signature 中的 key 部分,也可以是字符串和数字的字⾯量,标识符(baz, handler),也可以是 computed property name,⽐如 [Symbol.iterator]。它可以设置 readonly ,默认是可读可写的。
上⾯的每个 signature 结尾都带了⼀个 ; ,也可以选择使⽤ , ,也可以忽略。我⼀般是忽略不写,然后让 prettier 帮我补上,⾄于补上什么不重要,保持⼀致就好。
对于标识符是 computed property name 的情况,提两个⼩要点: ⽅括号内的部分,应该填写值空间的变量,你不能填写类型空间的内容。 对于类型字⾯量的⽅括号中间,我们只允许填写类型是 unique symbol 的值。
可索引类型
ES 2015 引⼊了 Map,所以我们需要实现 Map(有的地⽅也叫做 Dictionary)有了⽐较好的做法。在此之前,我们⼀般⽤ Object 当作Map 使⽤。Object 中的键值对,键只能是 string 和 symbol。取得值时候,通过 obj[key] 来取。如果输⼊的key不是字符串或者symbol,会被强制转型为字符串再继续操作。
可索引类型(Indexable Types) 是描述把 Object 当作 Dictionary 使⽤的时候的类型。
type Animal = {
name: string
age: number
}
type Foo = {
[key: string]: Animal;
}
const a: Foo = {};
a['foo'] = {
name: 'foo',
age: 2,
};
type ReadonlyFoo = {
readonly [key: string]: Animal;
};
const b: ReadonlyFoo = {
foo:{
name: 'foo',
age: 2,
}
}
const foo = b.foo // Animal
b['bar'] = foo; // Error: Index signature in type 'ReadonlyFoo' only permits reading
上⾯就是两个使⽤ indexable type 的例⼦。⽅括号内是⼀对冒号分割的内容。
⽅括号内冒号左边的是任意写的标识符,除了视觉效果,貌似没其他什么特定作⽤。我们常⽤的⼀般是 key 或者 index。当然你可以起成其他奇奇怪怪的标识符, foo,bar 啥的都可以。
⽅括号内冒号右边的是⼀个类型,叫做 index signature parameter type,⽽且 index signature parameter type 只能是类型关键字number 或者类型关键字 string,⼀个字母都不能差,你填写⼀个实际值是 number/string 的 type alias,填写⼀个字⾯量类型,填写⼀个 bigint 或者填写其他任何对类型的计算都不允许。
⽅括号的冒号后⾯的 Animal 叫做 index type,可以是任意类型,没有任何限制。如果 index signature parameter type 是 number 时候, index type 可以被叫做 numeric index type;如果 index signature parameter type 是 string 时候, index type 可以被叫做string index type。
整个类型,除去最外⾯的⼤括号,也就是 [key: string]: Animal; 叫做 index signature。
{ [key: string]: Animal } 也是⼀个 type literal。这也就暗⽰了,index signature 可以和 method signature 与 property signature ⼀起出现。
下⾯看⼀个例⼦:
type NumberDictionary = {
[index: string]: number;
length: 123; // 可以,length是number类型的⼦类型
[index: number]: string; // Error: Numeric index type 'string' is not assignable to string index type 'number'
name: string // Error: Property 'name' of type 'string' is not assignable to string index type 'number'.
}
type NumericIndex = {
parameter是什么意思啊[index: number]: string;
length: 123;
'1.1': 123; // Error: Property '"1.1"' of type '123' is not assignable to numeric index type 'string'
2333: '2333';
'0b11': 123;
0b11: '2333';
name: string;
};
如果⼀个 type literal 既有 numeric index signature ⼜有 string index signature 时候,我们要保证 numeric index type 是 string index type 的⼦类型。
如果⼀个 type literal 存在 string index signature 和 其他 signature(method signature,property signature) 时候,我们要保证其他的 signature 中的 type 是 string index type 的⼦类型。
如果⼀个 type literal 存在 numeric index signature 和 其他 signature(method signature,property signature) 时候,我们出其他的 key 是数字对应的字符串的 signature,⽐如 key 是 "1.1", 2333 或者 0b11 的 signature, 这些 signature 的 type 是numeric index type 的⼦类型。
例⼦
下⾯会出现⼀些没介绍过的,以后会介绍的语法。
这个语法的设计是为了如下的⽤途,举个例⼦,我们能知道⼀个对象的部分信息,⽐如我们使⽤⼀个对象表⽰环境变量。那么我们会写成:
type ProcessEnv = {
[key: string]: string | undefined;
}
上⾯的 | 是 union type,意思就是要么是 string 类型,要么是 undefined 类型。
如果我们知道部分信息,⽐如我们知道环境变量 PUBLIC_URL 肯定存在,则我们可以写成
type ProcessEnv = {
[key: string]: string | undefined;
PUBLIC_URL: string;
}
如果我们知道更多的信息,⽐如我们知道某些环境变量只可能是某些字段,我们会写成下⾯的样⼦
type ProcessEnv = {
[key: string]: string | undefined;
PUBLIC_URL: string;
NODE_ENV: 'development' | 'production' | 'test';
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论