New day, punch in and sign in. Json file version 0.0.5 and NPM run createDir as per Typescript type inference, the notes directory will be added with folder 0.0.5. Pretty simple, right? I’m going to ignore these simple operations in the next chapter and go straight to the topic.

Before we learned that object types were defined as objects, they are not. In Typescript gameplay, they are defined as Interfaces.

Gameplay (Introduction to interfaces)

In object-oriented languages, Interfaces are abstractions of behavior that can be understood in terms of the nature of things. The details of how to act are implemented by classes (implement) (you can use phenomena of things to assist in understanding).

Code (for example)

// interfaces.ts
interface Person {
    name: string;
    age: number;
}

let pr: Person = {
    name: 'fat rui',
    age: 30
}
Copy the code

Depending on the gameplay, the above example defines an interface Person (abstraction of behavior, nature of things), followed by a variable PR whose type is Person (interface is type, object type). Constrains that the variable pr attribute type must be the same as the interface Person.

In general, the interface starts with a capital letter (this can be understood with the React component name command rule).

Q: is it ok to define variables with fewer attributes than interfaces? How about one more?

// interfaces2.ts
interface Person2 {
    name: string;
    age: number;
}

let pr2: Person2 = {
    name: 'fat rui'
}

// 0.0.5/interfaces2.ts:6:5 - error TS2741: Property 'age' is missing in type '{name: string; }' but required in type 'Person2'.
    // 6 let pr2: Person2 = {

/ / 0.0.5 interfaces2. Ts: 3:5
    // 3 age: number;
    // 'age' is declared here.
Copy the code
// interfaces3.ts
interface Person3 {
    name: string;
    age: number;
}

let pr3: Person3 = {
    name: 'fat rui',
    age: 30,
    address: 'hangzhou'
}

// 0.0.5/interfaces3.ts:9:5 - error TS2322: Type '{name: string; age: number; address: string; }' is not assignable to type 'Person3'.
    // Object literal may only specify known properties, and 'address' does not exist in type 'Person3'.
    // 9 address: 'hangzhou'
Copy the code

The variable’s attributes must be the same as those of the interface (if the interface attributes are not handled).

Optional attribute

No more or less variable attributes can be assigned without doing anything to interface attributes. But sometimes we want some properties to be optional. Take a look

// interfaces4.ts
interface Person4 {
    name: string; age? :number;
}

let pr4: Person4 = {
    name: 'fat rui'
}

let pr4_1: Person4 = {
    name: 'fat rui',
    address: 'hangzhou'
}

/ / 0.0.5 interfaces4. Ts: "- error TS2322: Type '{name: string; address: string; }' is not assignable to type 'Person4'.
    // Object literal may only specify known properties, and 'address' does not exist in type 'Person4'.
    // 12 address: 'hangzhou'
Copy the code

The optional property is the property followed by? This is easy to understand (combined with re). Errors are still reported for redundant attributes (can’t turn a blind eye, how righteous).

Any attribute

Is there no other way? Check it out

// interfaces5.ts
interface Person5 {
    name: string; age? :number;
    [propName: string] :any;
}

let pr5: Person5 = {
    name: 'fat rui',
    isMan: true,
    address: 'hangzhou'
}
Copy the code

The compiled

// build/interfaces5.js
var pr5 = {
    name: 'fat rui'.isMan: true.address: 'hangzhou'
};
Copy the code

I love you, Typescript. You’re so human.

  • [propName: string]Defines any property with a key of typestring;
  • At this point, the type of any property is set toany, soisManaddressCan pass;

Think: Hang on, hang on. If an arbitrary attribute is set to string and an optional attribute is set to number, do they conflict?

// interfaces6.ts
interface Person6 {
    name: string; age? :number;
    [propName: string] :string;
}

let pr6: Person6 = {
    name: 'fat rui',
    age: 30,
    address: 'hangzhou'
}

// 0.0.5/interfaces6.ts:3:5 - error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
    // 3 age? : number;

// 0.0.5/interfaces6.ts:7:5 - error TS2322: Type '{name: string; age: number; address: string; }' is not assignable to type 'Person6'.
    // Property 'age' is incompatible with index signature.
    // Type 'number' is not assignable to type 'string'.
    // 7 let pr6: Person6 = {

/ / 0.0.5 interfaces6. Ts: mine - error TS2322: Type "string" is not assignable to Type 'number'.
    // 15 age: '30',

/ / 0.0.5 interfaces6. Ts: 3:5
    // 3 age? : number;
    // The expected type comes from property 'age' which is declared here on type 'Person6'
Copy the code

We can see from the above example that the error was reported and the reason for the error

  • ageAssignments can neither be numbers nor strings;
  • agenumberThe type is not arbitrarystringA subset of, soageI can’t assign it right;

So, we can change any property to any. There’s another solution, but it doesn’t make much sense.

// interfaces7.ts
interface Person7 {
    name: string; age? :number | string;
    [propName: string] :string | number;
}

let pr7: Person7 = {
    name: 'fat rui',
    age: 30,
    address: 'hangzhou'
}

let pr7_1: Person7 = {
    name: 'fat rui',
    age: '30',
    address: 'hangzhou'
}
Copy the code

Compiled by, through the variable assignment, the age of digital can also be used as a string, then we use joint type number | string, adjusted here, that also have to adjust any attribute, is also at least string | number, of course, for any better.

Read-only property

Having said optional and arbitrary properties, let’s look at another scenario: read-only properties. This is used when certain fields of an object are assigned only at creation time and cannot be changed later.

// interfaces8.ts
interface Person8 {
    readonly name: string; age? :number | string;
    [propName: string] :any;
}

let pr8: Person8 = {
    name: 'fat rui',
    age: 30,
    address: 'hangzhou'
}

pr8.age = 18; // Always 18
pr8.name = 'Fat Ray 2'; // I've seen too much of it


let pr8_1: Person8 = {
    address: 'hangzhou'
}

pr8_1.age = 18;
pr8_1.name = 'Fat Ray 3';

/ / 0.0.5 interfaces8. Ts: 14:5 - error TS2540: always assign to 'name' because it is a read - only the property.
    // 14 pr8.name = '1 '; // I've seen too much of it

/ / 0.0.5 interfaces8. Ts: 17:5 - error TS2741: the Property 'name' is missing in the type '{address: string; }' but required in type 'Person8'.
    // 17 let pr8_1: Person8 = {

/ / 0.0.5 interfaces8. Ts: 2:14
    // 2 readonly name: string;
    // 'name' is declared here.

/ / 0.0.5 interfaces8. Ts: only - error TS2540: always assign to 'name' because it is a read - only the property.
    // 22 pr8_1.name = '1 ';
Copy the code

In the example above, we can see that

  • Interface definition, we are innameAttributes are preceded by keywordsreadonly, meaning the property is read-only;
  • After assigning a value to a variableagenameReassign, herenameThe assignment line gives an error, which is what we want to see. 666;
  • The variablepr8_1When assigning, the property is readablenameIs not assigned (this error is easy to understand) and will be given laternameAssignment is an error because it’s a readable property, even though we didn’t assign it before;

As you can see, the constraint on a read-only property is the first assignment to the object, not the first assignment to the read-only property.

This code Github

You can…

Previous: Typescript type assertions

Next: Typescript array types

Contents: A primer to Typescript’s short book