当前位置:网站首页>[typescript] learn typescript object types in depth
[typescript] learn typescript object types in depth
2022-07-29 05:39:00 【Underwater barbecue shop AI】
Catalog
Preface
Bloggers' recent TypeScript
The articles are all here TypeScript special column in , Each article is a masterpiece carefully polished by bloggers , The quality score of almost every article has reached 99, And selected many times 【CSDN It's worth seeing every day 】 and 【 Comprehensive hot list of the whole station 】
Subscribe to a column to follow bloggers , Study TypeScript
Neverlost !
OK , Get down to business , Let's start to learn more TypeScript Object type :
stay 【TypeScript】TypeScript Common types ( Part 1 ) We have mentioned object types in , This article will explain it in depth
1、 Property modifier
Optional attribute
stay 【TypeScript】TypeScript Common types ( Part 1 ) We have already mentioned the optional properties of objects , Here we have a deeper understanding of it :
interface PaintOptions {
x?: number;
y?: number;
}
Use the interface to define an object type , The attributes are optional , stay 【TypeScript】TypeScript Common types ( Part 1 ) We already know that optional attributes cannot be used directly , It needs to be tested first Empty operation :
function ObjFn(obj: PaintOptions) {
if (obj.x && obj.y) {
// Judge the existence of optional attributes
console.log(obj.x + obj.y);
}
}
In fact, this is not the only way , We can also set a default value for optional attributes , When the attribute does not exist , Just use the default value we set , Here's an example :
function ObjFn({
x = 1, y = 2 }: PaintOptions) {
console.log(x + y);
}
ObjFn({
x: 4, y: 5 }); // log: 9
ObjFn({
}); // log: 3
ad locum , We are ObjFn
The parameter of uses a deconstruction pattern , And for x
and y
Default values are provided . Now? x
and y
Must exist in ObjFn
In the subject of , But for the ObjFn
Is optional for any caller of .
Read-only property
stay TypeScript
Use in readonly
Modifiers can define read-only attributes :
interface NameType {
readonly name: string; // Read-only property
}
function getName(obj: NameType) {
// Can read 'obj.name'.
console.log(obj.name);
// But you can't reset the value
obj.name = "Ailjx";
}
readonly
The modifier can only restrict a property itself from being rewritten , For properties of complex types , Its Inside It can still be changed :
interface Info {
readonly friend: string[];
readonly parent: {
father: string; mother: string };
}
function getInfo(obj: Info) {
// The normal operation
obj.friend[0] = "one";
obj.parent.father = "MyFather";
// Report errors
obj.friend = ["one"];
obj.parent = {
father: "MyFather", mother: "MyMother" };
}
TypeScript
When checking whether the properties of two types are compatible , Properties that do not consider these types are
No yes readonly
, therefore readony
Properties can also be changed by alias :
interface Person {
name: string;
age: number;
}
interface ReadonlyPerson {
readonly name: string;
readonly age: number;
}
let writablePerson: Person = {
name: "AiLjx",
age: 18,
};
// Normal work
let readonlyPerson: ReadonlyPerson = writablePerson;
console.log(readonlyPerson.age); // Print '18'
// readonlyPerson.age++; // Report errors
writablePerson.age++;
console.log(readonlyPerson.age); // Print '19'
It's a little winding here , So let's sort it out :
First, we declare two almost identical interface types
Person
andReadonlyPerson
, The difference isReadonlyPerson
The properties in are read-only .Then we define a type as
Person
The variable ofwritablePerson
, It can be seen that the value of the attribute in this variable is modifiable .The next interesting thing is
writablePerson
It can be assigned to the typeReadonlyPerson
The variable ofreadonlyPerson
, This provesTypeScript
When checking whether the properties of two types are compatible , Whether these types of properties arereadonly
, So the type isPerson
andReadonlyPerson
The data of can be assigned to each other .At this point, you need to understand variables
readonlyPerson
The properties inside are read-only , We go straight throughreadonlyPerson.age++
modifyage
It's a mistake , But the interesting thing is that we can passwritablePerson.age++
modifywritablePerson
Mediumage
, And because for data of reference type, direct assignment is just reference assignment ( namely Shallow copy ), thereforewritablePerson
After changereadonlyPerson
It's also changingsuch
readonlyPerson
The read-only attribute in was successfully modified
about
TypeScript
for , Read only properties do not change any behavior at run time , But during the type check , A property marked as read-only cannot be written .
Index signature
In some cases , We may not know the names of all attributes in the object , The attribute name is unknown , How do we define the type of this object ?
Now we can use a Index signature To describe the types of possible values :
interface IObj {
[index: string]: string;
}
const obj0: IObj = {
};
const obj1: IObj = {
name: "1" };
const obj2: IObj = {
name: "Ailjx", age: "18" };
The above is an object type defined with index signature , Pay attention to
index
It's self defined , Represents the placeholder of the attribute name , For objectsindex
The type of is generallystring
( Because of the object'skey
The value itself isstring
Type of , But there are exceptions , Just look down and see )final
string
It represents the type of attribute value , From this, we can easily find that the premise of using index signature is that you know the type of value .
At this time, careful friends should be able to find , When index
The type of number
when , You can represent an array , After all, an array is essentially an object , It's just that key
In fact, the index of the array is number
Type of :
interface IObj {
[index: number]: string;
}
const arr: IObj = [];
const arr1: IObj = ["Ailjx"];
const obj: IObj = {
}; // There will be no error when assigning an empty object
const obj1: IObj = {
1: "1" }; // assignment key Objects that are numbers will not report errors
index: number
Time can not only represent arrays , It can also represent the two objects shown above , This is the exception mentioned above .This is because when using " Numbers “ When indexing ,
JavaScript
In fact, it will be converted to... Before indexing to an object “ character string ”. This means using 1 ( A number ) Index and use "1” ( A string ) Indexing is the same , So the two need to be consistent .
The attribute type of index signature must be string
or number
, be called Digital indexer and String indexer , It is possible to support two types of indexers , But the type returned from the numeric indexer must be the type returned by the string indexer subtypes ( This point Of particular importance !), Such as :
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
interface IObj {
[index: number]: Dog;
[index: string]: Animal;
}
stay 【TypeScript】TypeScript Common types ( The next part ) We have already explained the extension of interface types , No more talk here , From the above code, we can know that
Dog
yesAnimal
Subclasses of , So the above code is optional , If you change the order, it won't work :
String index signature mandatory all Property of and its return type Match .
In the following example ,
name
The type of does not match the type of the string index , The type checker will give an error :There is no such restriction for digital index signatures
However , If the index signature is of attribute type union , Different types of attributes are acceptable :
interface IObj {
[index: string]: number | string;
length: number; // ok
name: string; // ok
}
The index signature can also be set to read-only :
2、 Extension type
stay 【TypeScript】TypeScript Common types ( The next part ) Interface In, we briefly introduced extension types , Let's talk more about it here :
interface User {
name: string;
age: number;
}
interface Admin {
isAdmin: true;
name: string;
age: number;
}
Two type interfaces are declared here , But it is found that they are actually related (Admin
yes User
A kind of ), And some attributes are repeated between them , It can be used at this time extends
Expand :
interface User {
name: string;
age: number;
}
interface Admin extends User {
isAdmin: true;
}
On the interface extends
keyword , Allows us to effectively copy members from other named types , And add any new members we want .
This is important for reducing the type declaration template we have to write , And several different declarations indicating the same attribute may be related to the intention , It's very useful . for example , Admin
There is no need to repeat name
and age
attribute , And because name
and age
From the User
, We will know that the two types are related to some extent .
Interfaces can also be extended from multiple types :
interface User {
name: string;
}
interface Age {
age: number;
}
interface Admin extends User, Age {
isAdmin: true;
}
Multiple parent classes use ,
Division
3、 Cross type
stay 【TypeScript】TypeScript Common types ( The next part ) Type the alias We have already introduced the cross type &
, I won't say too much here :
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
type ColorfulCircle = Colorful & Circle;
const cc: ColorfulCircle = {
color: "red",
radius: 42,
};
4、 Generic object type
If we have a box type , Its contents can be strings , Numbers , Boolean value , Array , Object, etc , Let's define it ? Is that so :
interface Box {
contents: any;
}
Now? , The property of any type of content is , It works , But we know that any
It can lead to TypeScript
Lost compile time type checking , This is obviously inappropriate
We can use unknown
, But this means that when we already know the content type , We need to do preventive tests , Or use error prone Types of assertions :
interface Box {
contents: unknown;
}
let x: Box = {
contents: "hello world",
};
// We need to check 'x.contents'
if (typeof x.contents === "string") {
console.log(x.contents.toLowerCase());
}
// Or use type assertions
console.log((x.contents as string).toLowerCase());
This seems a little complicated , And there is no guarantee TypeScript
Can trace contents
Specific types
In response to this demand , We can use Generic object type , Make one General purpose Box
type , Declare a type parameter :
// there Type Is custom
interface Box<Type> {
contents: Type;
}
When we quote Box
when , We must give one Type parameter Instead of Type
:
const str: Box<string> = {
contents: "999", // contents The type is string
}; // str Type equivalent to { contents:string }
const str1: Box<number> = {
contents: 1, // contents The type is number
}; // str1 Type equivalent to { contents:number }
Does this look like a function passing parameters ? In fact, we can completely Type
Understood as formal parameters , When using types, use generic syntax <>
Just pass in the arguments
In this way, we have achieved the desired effect ,contents
The type of can be any type we specify , also TypeScript
You can trace its specific type .
- More complex applications : Use generic object types to implement generic functions
interface Box<Type> {
contents: Type;
}
function setContents<FnType>(box: Box<FnType>, newContents: FnType): FnType {
box.contents = newContents;
return box.contents;
}
const a: string = setContents<string>({
contents: "Ailjx" }, "9");
console.log(a); // '9'
const b: number = setContents({
contents: 2 }, 2);
console.log(b); // 2
const c: boolean = setContents({
contents: true }, false);
console.log(c); // false
Here we use generics on functions , Type parameters are defined FnType
:setContents<FnType>
, Then the parameters of the function box
The type of Box<FnType>
( Pass the received parameters to Box
),newContents
The type of FnType
, The return value of the function is also FnType
type
Observation constant a
, It calls setContents
Function string
,string
Will replace setContents
All in function FnType
, Then the type of the two parameters of the function is {conents:string}
and string
, The return value of the function is also string
type
Actually, it is called here setContents
Function, we can not manually pass type parameters ,TypeScript
It will be very clever to infer from the type of parameters passed in by our calling function FnType
What is it? , It's like a constant b
and c
It's the same with
Type aliases are combined with generics
Type aliases can also be generic , We can use type aliases to redefine Box<Type>
:
type Box<Type> = {
contents: Type;
};
Because the type alias is different from the interface , It can not only describe object types , We can also use it to write other types of general auxiliary types :
type OrNull<Type> = Type | null;
type OneOrMany<Type> = Type | Type[];
type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;
type OneOrManyOrNullStrings = OneOrManyOrNull<string>;
In the above example, type aliases are nested , Think more about what is not difficult to understand
Common object types Usually some kind of container , Its work is independent of the type of elements they contain . It is ideal for data structures to work in this way , In this way, they can be reused in different data types .
5、 An array type
And the above Box
Same type , Array
It is also a general type , number[]
or string[] this
Actually, it's just Array<number>
and Array<string>
Abbreviation .
Array
Part of the source code of generic objects :
interface Array<Type> {
/** * Gets or sets the length of the array . */
length: number;
/** * Removes the last element in the array and returns . */
pop(): Type | undefined;
/** * Add a new element to an array , And returns the new length of the array . */
push(...items: Type[]): number;
// ...
}
modern
JavaScript
Other common data structures are also provided , such asMap<K, V>
,Set<T>
, andPromise<T>
. This actually means , becauseMap
、Set
andPromise
Behavior of , They can work with any type of collection .
6、 Read only array type
ReadonlyArray
It's a special type , Describes an array that should not be changed .
function doStuff(values: ReadonlyArray<string>) {
// We can 'values' Reading data ...
const copy = values.slice();
console.log(` The first value is ${
values[0]}`);
// ... But we can't change 'vulues' Value .
values.push("hello!");
values[0] = "999";
}
ReadonlyArray<string>
Like ordinary arrays, it can also be abbreviated , It can be abbreviated as :readonly string[]
ordinary
Array
Can be assigned toReadonlyArray
:const roArray: ReadonlyArray<string> = ["red", "green", "blue"];
and
ReadonlyArray
Cannot be assigned to ordinaryArray
:
7、 A tuple type
Tuple
Type is another Array
type , It knows exactly how many elements it contains , And what types it contains in a particular location .
type MyType = [number, string];
const arr: MyType = [1, "1"];
there MyType
Is a tuple type , For type systems , MyType
Describe its rope
lead 0 Contains numbers and Indexes 1 An array of strings , An error will be thrown when the type does not match :
When we try to index more than the number of elements , We'll get a mistake :
It should be noted that :
Here we only declare the types of the first two elements of the array , But this does not mean that there can only be two elements in the array
We can still learn from it
push
The new element , But the type of the new element must be one of the types we declaredAnd after adding new elements, although the length of the array has changed , But we still can't access the newly added elements through the index ( The accessible index still does not exceed the number of elements in the previous type definition )
const arr: MyType = [1, "1"]; arr.push(3); arr.push("3"); console.log(arr, arr.length); // [ 1, '1', 3, '3' ] 4 console.log(arr[0], arr[1]); // 1 '1' // console.log(arr[2]); // err: The length is "2" The tuple type of "MyType" In the index "2" There is no element . // arr.push(true); // err: type “boolean” Argument to cannot be assigned to type “string | number” Parameters of
Deconstruct tuples :
function fn(a: [string, number]) {
const [str, num] = a;
console.log(str); // type str=string
console.log(num); // type num=number
}
It should be noted here that the data we deconstruct is a constant , Cannot be modified :
function fn(a: [string, number]) { const [str, num] = a; console.log(a[1]++); // ok console.log(num++); // err: Unable to assign to "num" , Because it's a constant }
Optional tuples
Tuples can be created by adding ?
Make it optional , It can only appear at the end of the array , And it can also affect the length of the array .
type MyArr = [number, number, number?];
function getLength(arr: MyArr) {
const [x, y, z] = arr; // z The type of number|undefined
console.log(` The length of the array :${
arr.length} `);
}
getLength([3, 4]); // The length of the array :2
getLength([3, 4, 5]); // The length of the array :3
getLength([3, 4, "5"]); // err: You can't type “string” Assign to type “number”.
The rest of the elements
Tuples can also have The rest of the elements , These elements must be array/tuple
type :
type Arr1 = [string, number, ...boolean[]];
type Arr2 = [string, ...boolean[], number];
type Arr3 = [...boolean[], string, number];
const a: Arr1 = ["Ailjx", 3, true, false, true, false, true];
Arr1
Describes a tuple , The first two elements are string and number , But any number of Booleans can follow .Arr2
Describes a tuple , The first element is the string , Then there are any number of Boolean operations , Finally, there is a number .Arr3
Describes a tuple , The starting element is any number of Boolean operations , Finally, there is a string , Then there is a number .
application
function fn(...args: [string, number, ...boolean[]]) {
const [name, version, ...input] = args;
console.log(name, version, input); // 1 1 [ true, false ]
console.log(' The number of arguments :',args.length); // The number of arguments :4
// ...
}
fn("1", 1, true, false);
Almost equal to :
function fn(name: string, version: number, ...input: boolean[]) {
console.log(name, version, input); // 1 1 [ true, false ]
console.log(input.length + 2); // The number of arguments :4
// ...
}
fn("1", 1, true, false);
8、 Read only tuple type
tuple
The type has a read-only attribute , You can add a readonly
Modifier to specify :
let arr: readonly [string, number] = ["1", 1];
arr[0] = "9"; // err: Unable to assign to "0" , Because it's a read-only property .
In most code , Tuples are often created and not modified , So when possible , Annotating types as read-only tuples is a good default .
with const
The array literal asserted will be inferred as a read-only tuple type , And the type of element is text type :
As in the read-only array type , Ordinary tuples can be assigned to read-only tuples , But not vice versa :
let readonlyArr: readonly [number, number];
let arr1: [number, number] = [5, 5];
readonlyArr = arr1; // ok
let arr2: [number, number] = readonlyArr; // err
Conclusion
Last article 【TypeScript】TypeScript Medium type reduction ( Including type protection ) And type predicates I've been selected 《 Comprehensive hot list of the whole station 》, thank CSDN And my friends who support me , I will continue to work hard , Keep your state and create more and better articles !
边栏推荐
- 用threejs 技术做游戏跑酷
- 利用Poi-tl在word模板表格单元格内一次插入多张图片和多行单元格相同数据自动合并的功能组件
- Day 5
- js简单代码判断打开页面的设备是电脑PC端或手机H5端或微信端
- Integer overflow and printing
- Solve the problem that the prompt information of form verification does not disappear and the assignment does not take effect
- 弹性盒子flex
- 微信小程序-组件传参,状态管理
- The function of using wechat applet to scan code to log in to the PC web of the system
- uniapp之常用提示弹框
猜你喜欢
Introduction to C language array to proficiency (array elaboration)
365 day challenge leetcode 1000 questions - day 035 one question per day + two point search 13
ClickHouse学习(二)ClickHouse单机安装
【C语言系列】— 把同学弄糊涂的 “常量” 与 “变量”
HCIA-R&S自用笔记(26)PPP
ClickHouse学习(十一)clickhouseAPI操作
Question swiping Madness - leetcode's sword finger offer58 - ii Detailed explanation of left rotation string
shell基本操作(下)
[C language series] - three methods to simulate the implementation of strlen library functions
【JS题解】牛客网JS篇1-10题
随机推荐
Li Kou 994: rotten orange (BFS)
Day 2
【JS题解】牛客网JS篇1-10题
表格与表单相关知识点总结
小程序中的DOM对象元素块动态排序
H5语义化标签
基础爬虫实战案例之获取游戏商品数据
解决表单校验提示信息不消失问题以及赋值不生效问题
Clickhouse learning (VIII) materialized view
利用Poi-tl在word模板表格单元格内一次插入多张图片和多行单元格相同数据自动合并的功能组件
Day 5
微信小程序-组件传参,状态管理
Clickhouse learning (x) monitoring operation indicators
[C language series] - three methods to simulate the implementation of strlen library functions
Basic use of redis
[sword finger offer] - explain the library function ATOI and simulate the realization of ATOI function
HCIA-R&S自用笔记(27)综合实验
第三课threejs全景预览房间案例
paddle.fluild常量计算报错‘NoneType‘ object has no attribute ‘get_fetch_list‘
uniapp组件之倒计时(如阅读协议倒计时、完成学习倒计时)