TS compatibility
This chapter is part of the notes of learning TS by yourself, watching the videos on the official website and finding information
This TS compatibility check looks a little bit on the website, but is actually quite difficult to understand
For the record, this is a collection of TS compatibility
If you want to see TS function compatibility, you can skip to the section on function compatibility
To read on, first understand what TS compatibility is?
The principle of compatibility is duck-check, i.e
The type check will pass if an attribute in the type of the variable being assigned exists in the type of the source being assigned
Interface compatibility
If the variable type passed by a function does not match the declared type, TS checks for compatibility
interface Animal {
name: string;
age: number;
}
interface Person {
name: string;
age: number;
gender: number
}
// Determine if the target type 'Person' is compatible with the input source type 'Animal'
function getName(animal: Animal) :string {
return animal.name;
}
let p = {
name: 'lzy'.age: 25.gender: 0
}
getName(p);
// Only when the parameter is passed will the two variables be compared for compatibility.
// The assignment does not compare, and an error is reported directly
let a: Animal = {
name: 'lzy'.age: 25.gender: 0 / / an error
}
Copy the code
In the third article, TS Interface,
Object literals undergo additional property checking when taken directly as arguments
If you write it as an object and pass it as a parameter to a function call, you don’t check for extra properties on the object,
Obviously, calling a function passes in an object literal directly, which is equivalent to assigning a parameter (to a variable) directly, while
No compatibility check is performed on variable assignments. Additional attributes are not allowed.
Function calls passing parameters are tolerated in the case of passing a variable whose value is an object, allowing compatibility
Function calls with extra property literals assigned to the object as arguments, and passed in as arguments.
This is because THE TS considers that variable checks have already been done when the object is assigned, so it is safe to allow compatibility.
Base type compatibility
// Basic data types are also compatible
let num : string|number;
let str:string='zhufeng';
num = str;
String variables can be assigned as long as the toString() method is present
let num2 : {
toString():string
}
let str2:string='jiagou';
num2 = str2;
Copy the code
Class compatibility
When comparing the class types of two variables, only the instance members are compared
Private and protected members of a class affect compatibility. When checking the compatibility of class instances, if the target type contains a private member, the source type must contain that private member from the same class. Similarly, this rule applies to type checking that contains instances of protected members. This allows subclasses to assign to their parents, but not to other classes of the same type.
class Animal {
feet: number;
// If name is preceded by public, then a = s is an error because modifiers are added to the instance
constructor(name: string,numFeet: number){}}class Size {
feet: number;
// If numFeet and numFeet are set to public, the two equations are still valid
// If numFeet and numFeet are private, both equations are wrong
constructor(numFeet: number){}}let a: Animal;
let s: Size;
a = s; // OK
s = a; // OK
Copy the code
When comparing instance parts of a class, only the structure of the instance part is compared, regardless of the type name
class Animal{ name:string }
class Bird extends Animal{ swing:number }
let a:Animal = new Bird();
// Not Java's 'parent compatible subclass, but subclass incompatible parent class'
// Just because bird needs an attribute swing:number, new Animal() not available
let b:Bird = new Animal(); / / an error
Copy the code
The following example shows that it doesn’t matter whether the type is a subclass parent, as long as the structure matches
class Animal{ name:string }
// If the parent class has the same structure as the subclass, this works fine
class Bird extends Animal{}
let a:Animal = new Bird();
let b:Bird = new Animal();
// Two completely unrelated classes can also be assigned to each other, as long as the structure matches
Copy the code
Function compatibility
A function assigns a value to a variable by comparing its arguments and then its return value
type sumFunc = (a:number,b:number) = >number;
let sum:sumFunc;
function f1(a:number,b:number) :number{
return a+b;
}
// You can omit an argument
function f2(a:number) :number{
return a;
}
sum = f2;
// Two arguments can be omitted
function f3() :number{
return 0;
}
// Add one more parameter
function f4(a:number,b:number,c:number){
return a+b+c;
}
sum = f1;
sum = f2;
sum = f3;
sum = f4; / / an error
// An object that returns a value can have more attributes than the variable requires
Copy the code
The function that assigns a value to a variable requires fewer arguments than the function that assigns a value to a variable requires more arguments than the function that assigns a value to a variable
Parent-class compatibility of function plus argument types
When assigning a function to a variable whose type is defined
A function assigned to a variable
Arguments can have fewer attributes than those required in the variable type definition (contravariant)
The return value can be more than the required attribute in the variable type definition (covariant)
Simplified version:
Function parameters that assign values to variables can have fewer attributes and return values can have more attributes.
To understand:
The parameters of the function used for assignment must have fewer attributes than the variable being assigned
The return value of the function used to assign must have more properties than the variable to which it is assigned.
In practice, in type checking, only the type of the variable is checked, not the type of the value to which the variable is assigned (since values are mutable, the point is that the value has already been checked when the variable is assigned).
If the return value of the function used for assignment is not required to have an attribute equal to or greater
Later use of the variable will occur,
When type checking, it is allowed to use an attribute of the return value (because the variable type constraint says yes),
The return value of this attribute is undefined(because the real function value of the variable returns less value than the constraint value of the variable class).
An execution error occurs.
If you do not require that the parameters of the function used for assignment have attributes equal to or less
This occurs when the variable is later used
When checking the type of A variable, it is allowed to use the variable A to call the variable.
When the compiler executes, it is found that variable A is missing an attribute (because the real function value of A variable requires more parameter attributes than the variable type constraint).
An execution error occurs
class Animal{}
class Dog extends Animal{
public name:string = 'Dog'
}
class BlackDog extends Dog {
public age: number = 10
}
class WhiteDog extends Dog {
public home: string = 'Beijing'
}
let animal: Animal;
let blackDog: BlackDog;
let whiteDog: WhiteDog;
// Error: the dog parameter is incompatible with the blackDog parameter.
// blackDog argument qualified functions require age attributes. Dog argument qualified variables are not mandatory.
// Assume no error here
// The call function can be of type dog through the childToChild variable
// The function value requires the age attribute of type blackDog
const childToChild: (dog: Dog) = >Dog = (blackDog: BlackDog): BlackDog= > {
// The return value is changed to blackDog with more attributes.
return new BlackDog()
}
// Error: the dog parameter is incompatible with the blackDog parameter. BlackDog requires age, but dog does not.
const childToParent: (dog: Dog) = >Dog = (BlackDog: BlackDog): Animal= > {
// Error: The return value is changed to blackDog, which has fewer attributes.
return new Animal()
}
// The argument is an aniamal that requires fewer attributes
const parentToParent: (dog: Dog) = >Dog = (animal: Animal): Animal= > {
// Error: the return value cannot be of the animal type with fewer attributes, only of the animal class with more attributes
return new Animal()
}
// Completely OK, the type attribute of the function parameter used for assignment requires fewer type attributes and more type attributes of the return value parameter
const parentToChild: (dog: Dog) = >Dog = (animal: Animal): BlackDog= > {
return new BlackDog()
}
//(Animal → Greyhound) ≼ (Dog → Dog)
Copy the code
Compatibility with generics
To be clear, an interface is a type and a type, and a generic type needs to be converted to a specific type
Rule: Determine the specific type of the incoming generic T, and then determine compatibility
//1. The interface content is empty or as useless as the generic or passed T
// or T of y is equal if it is a subclass of T of x
interface Empty<T>{
name:string
}
letx! :Empty<string>;
lety! :Empty<number>;
x = y;
//2. Interface contents are not equal when they are not empty
interface NotEmpty<T>{
data:T
}
letx1! :NotEmpty<string>; / /! Not empty assertion
lety1! :NotEmpty<number>;
x1 = y1; / / an error
// Demo2 is equivalent to the following
interface NotEmptyString{
data:string
}
interface NotEmptyNumber{
data:number
}
letxx2! :NotEmptyString;letyy2! :NotEmptyNumber; xx2 = yy2;/ / an error
Copy the code
If it is a generic type with no specified type, T is treated as any
let identity = function<T> (x: T) :T {}let reverse = function<U> (y: U) :U { }
identity = reverse; // OK, because (x: any) => any matches (y: any) => any
Copy the code
Enumeration compatibility
Enumeration types are compatible with numeric types
Different enumeration types are incompatible
// Numbers can be assigned to enumerations
enum Colors {Red=1,Yellow=2}
enum Colors2 {Red=1,Yellow=2}
let c:Colors;
let c2:Colors2;
c = Colors.Red;
c = 1;
c = '1'; / / an error
c = Colors2.Red / / an error
// Enumeration values can be assigned to numbers
let n:number;
n = 1;
n = Colors.Red;
Copy the code
The last
Rookie understand, there may be some mistakes, the big guy mercy, at the same time thanks for your advice.
Humbly recommend a wave of personal website Luo Ziyu’s blog, although in fact there is nothing