The type of object - Interface
In TypeScript, we use the type of interface (Interfaces) to define the object.
What is the interface
In object-oriented languages, interfaces (Interfaces) is a very important concept, it is an abstract behavior, and how specific actions need to be implemented by the class (classes) (implement).
TypeScript The interface is a very flexible concept that can be used in addition to a portion of the behavior of the abstract class outside, it is also often used to "shape (Shape) object" description.
Simple example
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
In the above example, we define an interface Person
, and then defines a variable tom
, its type Person
. Thus, we constrain tom
the shape of the interface and must be Person
consistent.
Interfaces are typically capitalized. Name of the interface and some programming language would suggest adding I
a prefix .
Variables defined interfaces less than some of the properties is not allowed:
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom'
};
// index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
// Property 'age' is missing in type '{ name: string; }'.
Some multi-attribute is not allowed:
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// index.ts(9,5): error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
// Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
Visible, when assigned, the shape of the variables and the shape of the interface must be consistent .
Optional attributes
Sometimes we do not want to completely match a shape, you can use the optional attributes:
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom'
};
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
Optional attribute meaning that the property may not exist.
Then still not allowed to add undefined property :
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// examples/playground/index.ts(9,5): error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
// Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
Any property
Sometimes we want an interface that allows arbitrary attributes, you can use the following ways:
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
Use [propName: string]
define any attribute takes a string
value type.
Note that, once any of the attributes defined, to determine the properties and type of optional attributes must be a subset of its type :
interface Person {
name: string;
age?: number;
[propName: string]: string;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
// index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'.
// Index signatures are incompatible.
// Type 'string | number' is not assignable to type 'string'.
// Type 'number' is not assignable to type 'string'.
In the embodiment, the value allowed to be any property string
, but optional attribute age
value is number
, number
not a string
sub-property, so the error.
Further, it can be seen in the error message, in which case { name: 'Tom', age: 25, gender: 'male' }
the type is inferred become { [x: string]: string | number; name: string; age: number; gender: string; }
, which is a combination of the type and the joint interface.
Read-only attribute
Sometimes we want the object to some of the fields can only be assigned at the time of creation, you can readonly
define the read-only attribute:
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.
In the embodiment, using readonly
the attribute definition id
after initialization has been assigned, so the error.
Note that read-only constraint is present in the first assignment to the object, not when the first time to the read-only attribute assignment :
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.
In the embodiment, there are two error message, the first is that of tom
the time of assignment, not to id
assign.
In second place is given tom.id
the assignment of the time, because it is read-only attribute, so the error.
- This article refers to xcatliu