This is the 8th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Type of object
Next, let’s look at an example like this:
// Define an interface, usually with a capital letter
interface Person {
name: string;
age: number;
}
// Constrain this variable to the format of the interface. When defining name and age, it must also satisfy the type required by the interface
let alex: Person = {
name: 'Alex'.age: 20
}
Copy the code
When you add an interface, you can separate each entry with a semicolon or comma, or you can add nothing at all.
Note that if our variable is missing one of its attributes, it will report an error
Of course, an error can also be reported if one attribute is redundant.
// An attribute is missing
interface Person {
name: string;
age: number;
}
let alex: Person = {
name: 'Alex'
}
// An attribute is redundant
interface Person {
name: string;
age: number;
}
let alex: Person = {
name: 'Alex'.age: 20.gender: 'male'
}
Copy the code
Sometimes, however, we want an interface whose properties are optional. We can add a question mark.
/ /? : indicates optional. Mark this attribute as optional
interface Person {
name: string; age? :number;
}
let alex: Person = {
name: 'Alex'
}
Copy the code
Sometimes, we can’t predict what new properties it has. At this point, we need to use arbitrary properties.
Note that:
- Any attribute must contain all of the above data types. For that error, use the union type
- PropName can be changed to another name, such as x or y
interface Person {
name: string; age? :number;
// [propName: string]: any; / / normal
// [propName: string]: string; / / an error
// Any attribute must contain all of the above data types. For that error, use joint type processing
[propName: string] :string | number;
}
let alex: Person = {
name: 'Alex'.gender: 'male'
}
Copy the code
Exercise: variablesanimal
What types can be declared?
const animal: _____ = {
weight: 10.isMammal: true
}
Copy the code
A. any
B. number | boolean
C. { number | boolean }
D. { weight: number; isMammal: boolean; }
The answer
A D
parsing
The variable animal is assigned to an object, so the variable animal should be declared as a specific object type.
- A – Any variable of indeterminate type can be declared as
any
Is correct. - B – The union types of this option are all basic data types. So the mistake.
- C – Wrong way to write it.
- D – This option is an object type, and the structure type matches the assignment object structure type, so it is correct.
Data: Read-only property
In the daily development process, it is common for the object values to be overwritten due to multiple people working together or the complexity of the project. So it is important to be able to detect such errors during the coding phase and prevent compilation. As it happens, TypeScript gives us the ability to define read-only attributes using readonly:
interface Person {
readonly id: number;
name: string; age? :number;
[propName: string] :any;
}
let tom: Person = {
id: 89757.name: 'Tom'.gender: 'male'
};
tom.id = 9527;
// index.ts(14,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
Copy the code
In the above example, the attribute ID defined by readonly was initialized and then assigned again, so an error was reported.
Note that the read-only constraint exists the first time an object is assigned, not the first time a read-only property is assigned:
interface Person {
readonly id: number;
name: string; age? :number;
[propName: string] :any;
}
let tom: Person = {
name: 'Tom'.gender: 'male'
};
tom.id = 89757;
// index.ts(8,5): error TS2322: Type '{name: string; gender: string; }' is not assignable to type 'Person'.
// Property 'id' is missing in type '{ name: string; gender: string; } '.
// index.ts(13,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
Copy the code
In the example above, there are two error messages. The first one is that the assignment to Tom is not given to id.
The second error occurs when assigning tom.id because it is read-only.
Type inference – objects
Continuing with the previous example, what does type inference look like in an object?
interface Person {
name: string; age? :number;
[propName: string] :string | number;
}
let alex: Person = {
name: 'Alex'.gender: 'male'
}
Copy the code
What about putting the type definition directly where the variable definition is? In this case, we can dispense with the interface
let alex: { name: string; age? : number; [propName: string]: string | number; } = { name: 'Alex', gender: 'male' }Copy the code
Now Alex is the type defined later. If we omit this whole list of types that we’re going to define.
Alex, in this case, will automatically deduce the type based on its value.
Complex object
So what we’ve seen so far is a simple object that has one level, but what if this object has multiple levels? How would TS describe it?
let alex: Person = {
name: 'Alex'.gender: 'male'.friend: {
name: 'Lucy'.age: 18}}Copy the code
Can we just say that in interface? The answer is yes.
interface Person {
name: string;
gender: string;
friend: { // Object structure
name: string;
age: number; }}// This will describe the alex type correctly
let alex: Person = {
name: 'Alex'.gender: 'male'.friend: {
name: 'Lucy'.age: 18.// gender: 'female' // Error reported}}Copy the code
Problem: In strictly typed mode, variablesanimal
The type of
const animal = {
weight: 10.isMammal: true
}
Copy the code
A. any
B. number | boolean
C. { number | boolean }
D. { weight: number; isMammal: boolean; }
Answer: D
parsing
The variable animal is assigned to an object, so the variable animal is inferred to the specific object type.
- A –
any
Not a concrete object type, error. - B – The union types of this option are all basic data types. So the mistake.
- C – Wrong way to write it.
- D – This option is an object type, and the structure type matches the assignment object structure type, so it is correct.