Their definition files are also in the TypeScript core # TS note foundation
1. Primitive data type
JavaScript types are divided into two types: primitive data types (Primitive data types) and object types (Object types).
Primitive data types include: 字符串
, 数字
, 布尔值
, null
, undefind
newly added in es6 symbol
and new in es10 bigInt
.
Boolean value
let isDone:boolean = false;
// 编译通过
// 后面约定,未强调编译错误的代码片段,一律未编译通过
Note that the created using the constructor boolean
is not a boolean
let isDone:boolean = nwe Boolean(1);
// Type 'Boolean' is not assignable to type 'boolean'.
// boolean' is a primitive, but 'Boolean' is a wrapper object.
// Prefer using 'boolean' when possible.
What you create with Boolean is not a boolean, it's actually an boolean
object.
In TypeScript, boolean
it represents the basic data type, and Boolean
is a constructor of JavaScript. Same as other basic types (except undefined
and null
).
value
use number
definition type
let decLiteral:number = 6;
let hexLiteral: number = 0xf00d;
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
let infinityNumber: number = Infinity;
string
use string
definition type
let myName:string = '小明';
leg age:string = '18';
let my:string = `我的名字${
age}`;
empty value
There is no concept of JavaScript
null value ( ) in , in general null value is used for function return.void
TypeScript
function alertName():void{
alart('我是图图小可爱')
return;
// return 不能返回结果,
}
void
The function returns or does not return, in fact, the null value is also a return, return empty
Undefind and Null
Use undefind
and null
define types
let u:undefind = undefind;
let n:null = null;
void
The difference with is that undefind
and null
are subtypes of all types. That is to say undefind
, null
all variables of the defined type can be assigned
let s:string = undefind;
let s1:string = null;
let num:number = undefind;
let num1:number = null;
A variable of type cannot void
be assigned to number
a variable of type
let u:void;
let num:number = u;
// Type 'void' is not assignable to type 'number'.
2. Any value
Any value (any) means to allow assignment to any value. Generally not used.
what is an arbitrary value
let s1:string = 'seven';
s1 = 10;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'
Changing from string to number is not allowed, but if it is any
a type, it is allowed to be assigned to any type
let s1:any = 'seven';
s1 = 10
Properties and methods with arbitrary values
Access to any property on any value is allowed
let anyTing:any = 'hello';
console.log(anyTing.myName);
console.log(anyTing.firstName)
Access to any method on any value is allowed
let anyTing:any = 'Tom';
anyTing.setName('Jeary');
anyTing.setName('Jeary').setHello();
It can be considered that after declaring an arbitrary value, how to operate it and the type of the returned content are all arbitrary values.
undeclared type
let someTing;
someTing = 10;
someTing = '你好';
Equivalent to
let someTing:any;
someTing = 10;
someTing = '你好';
The variable declares an unassigned type, which defaults to an arbitrary value type.
3. Type inference
If no type is explicitly specified, TypeScript will 类型推论
infer a type according to the rules from
What is type inference
let myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.
In practice, it would be equivalent to:
let myFavoriteNumber:string = 'seven';
myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.
TypeScript will infer a type when there is no explicit specified type, which is type inference.
If the declaration does not define a type, it will be inferred to be any
the type regardless of subsequent assignments
let someTing;
somgTing = 'seven';
someTing = 7
4. Joint type
A union type means that it can take one of many types
what is a union type
let s1:number | string = 10;
s1 = 'seven';
s1 = 1;
Union types use |
a to separate each type.
Here s1 means that the allowed type is number
and string
, but not other types
Access to a property or method of a union type
function fn(s1:string|number):number{
return s1.length
}
// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string|number'.
// Property 'length' does not exist on type 'number'.
Access is not a common method of string
andnumber
Accessing shared properties of string
and number
is no problem:
function fn(s1:string|number):number{
return s1.toString()
}
When a variable of a union type is assigned a value, a type will be inferred according to the rules of type inference:
let s1:string | number;
s1 = '1111';
console.log(s1.length);
s1 = 7;
console.log(s1.length) // 报错
5. The type of object - interface
Define types using objects
let name:{
};
let name1:object;
In general practice, we don't define the type in this way. If it is defined in this way, the properties in the object are equivalent to any
the type
let nName:{
name:string,age:number};
The type defined in the specified object must be kept consistent name
with age
the attribute name, neither more nor less
let nName:{
name:string,age?:number};
The representation passed by the current object name ?.
can be passed or not;
let nName:{
name:string,age?:number,[propName:string]:any}
[propName:string] indicates that an unknown property is passed in, which must be of string type, and [propName:string]:any any
indicates that the subtype can be any value
let nName:{
name:string,age?:number,[propName:string]:string}
The specified subtype is string
, if the age attribute is passed in, an error will be reported, and the type is string.
This kind of problem can usually be solved by union type
let nName:{
name:string,age?:number,[propName:string]:string|number}
what is an interface
In TypeScript, we use interfaces (Interfaces) to define the type of an object.
In the object-oriented language, there is a very important concept, which is the abstraction of behavior, and how to act specifically needs to be implemented by the class (implement)
The interface of TypeScript is a very flexible concept. In addition to abstracting part of the class, it can also describe the shape of the class.
simple example
interface Person{
name:string,
age:number
}
let zhangshan:Person{
name:'张三',
age:16
}
Person
The named interface is defined , zhangsan
and the shape of the object must be the Person
same as that of the object. Generally, the name of the interface is capitalized to distinguish it.
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; }'.
It is not allowed to define variables with fewer attributes than interfaces
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'.
More attributes are not allowed
It can be seen that when assigning a value, the shape of the variable must be consistent with the shape of the interface .
optional attributes
Sometimes we don't want to match a shape exactly, so we can use optional attributes:
interface Person{
name:string,
age?:number
}
let tom:Person={
name:"丈夫"
}
// age可传可不传
At this time, **still not allowed to add new undefined attributes**
any attribute
Sometimes we want an interface to allow arbitrary attributes, we can use the following method
interface Person{
name:string,
age?:number,
[proprsName:string]:any
}
let tom:Person={
name:"丈夫",
sss:1231231
}
Using [propName: string]
defines that any property takes string
a value of type .
It should be noted that once any attribute is defined, the type of both the definite attribute and the optional attribute must be a subset of its type
interface Person{
name:string,
age?:number,
[proprsName:string]:string
}
let tom:Person={
name:"丈夫",
sss:"1231231"
}
Specify any type as a string, and you still cannot add undefined properties at this time
interface Person{
name:string,
age?:number,
[proprsName:string]:string
}
let tom:Person={
name:"丈夫",
age:10
sss:"1231231"
}
// 报错,指定了sss子类型为string类型,age的类型为number
The value of any attribute is allowed to be string
, but the value of the optional attribute age
is number
, number
not string
a sub-attribute of , so an error is reported. Note that an interface can only specify one arbitrary type
Only one arbitrary property can be defined in an interface. If you have properties of more than one type in the interface, you can use union types in any of the properties:
interface Person{
name:string,
age?:number,
[proprsName:string]:string|number
}
let tom:Person={
name:"丈夫",
age:10
gender:"男"
}
read-only attribute
interface Person{
readonly id:number,
name:string,
age?:number,
[proprsName:string]:string|number
}
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 above example, after initialization using readonly
the defined property id
, it is assigned a value, so an error is reported
Note that the read-only constraint exists when the object is first assigned a value, not when the read-only property is assigned for the first time :
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
tom.id = 89757;
// 1. id未传 报错 2.id为只读,进行了第二次赋值 报错
6. The type of the array
In TypeScript, there are many ways to define the type of array, which is more flexible
[type + square brackets] notation
let fibonacci:number[] = [1,2,3,4,5];
Other types are not allowed in the array
let fibonacci:number[]= [1,'we',2,3]
// Type 'string' is not assignable to type 'number'.
The parameters of some methods of the array will also be restricted according to the type agreed upon when the array is defined
let fibonacci:number[]= [1,'we',2,3]
fibonacci.push('8')
// Argument of type '"8"' is not assignable to parameter of type 'number'.
It is required to pass in number
the type, but string
the type is passed in, and an error is reported
array generics
We can also use Array Generic Array
to represent arrays
let fibonacci :<Array>number = [1,2,3,4,5];
Using interfaces to represent array types
interface ArrayNumber{
[propsName:number]:number
}
Although interfaces can also be used to describe arrays, we generally don't do this because this method is much more complicated than the first two methods.
However, there is one exception, that is, it is often used to represent array-like .
array-like
Array-like (Array -like Object) is not an array, such asarguments
function fn(){
let args:number[] = arguments;
}
// Type 'IArguments' is missing the following properties from type 'number[]': pop, push, concat, join, and 24 more.
In the above example, arguments
it is actually a class array, which cannot be described in the way of an ordinary array, and the description is not comprehensive. It is impossible for the array to be all numbers, but it should be defined in the way of an interface
function fn(){
let args:{
[index:number]:number,
length:number,
callee:Function,
} = arguments;
}
In this example, in addition to constraining that when the index type is a number, the value type must be a number, we also constrain it to have length
and callee
two attributes.
In fact, commonly used class arrays have their own interface definitions, such as IArguments
, NodeList
, HTMLCollection
etc.
functions sum(){
let args:IArguments = arguments;
}
Among them IArguments
is the type defined in TypeScript, which is actually:
interface IArguments{
[index:number]:number,
length:number;
callee:Function;
}
The use of any in an array
A more common way is to use to any
indicate that any type is allowed in the array:
let list:<Array>any = ['xcatilu',25,{
website:"http://localhost:3000"}]
7. Types of functions
Functions are first-class citizens of JavaScript
Function declaration (anonymous function)
In JavaScript, there are two common ways of defining functions – anonymous function (Function Declaration) and function expression (Function Expression)
// 匿名函数
function sum(x,y){
return x+y;
}
// 函数表示式
const sun = function(x,y){
return x+y;
}
A function has input and output. To constrain it in TypeScript, both input and output need to be considered. The type definition of the function declaration is relatively simple:
function (x:number,y:number):number{
return x+y
}
Note that entering extra (or less than required) parameters is not allowed :
function sum(x: number, y: number): number {
return x + y;
}
sum(1, 2, 3);
// index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
function sum(x: number, y: number): number {
return x + y;
}
sum(1);
// index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
function expression
If we were to write a definition of a function expression (Function Expression) now, it might be written like this:
let sum = function(a:number,b:number):number{
return a+b
}
However, this is actually a type definition for function, and the sum on the left is inferred. The correct way of writing is
let sun:(x:number,y:number)=>number=function(x:number,y:number):number{
return x+y;
}
Be careful not to confuse TypeScript's =>
with ES6's =>
.
In the type definition of TypeScript, =>
it is used to represent the definition of a function. The left side is the input type, which needs to be enclosed in parentheses, and the right side is the output type.
Define the shape of a function with an interface
We can also use interfaces to define the shape that a function needs to conform to
interface SearchFunc {
(source:string,subString:string):boolean;
}
let mySearch:SearchFunc;
mySearch=function(source:string,subString:string){
return source.search(subString)!==-1;
}
When using the method of function expression|interface to define a function, the type restriction on the left side of the equal sign can ensure that the number of parameters, parameter types, and return value types remain unchanged when assigning a function name in the future.
optional parameters
As mentioned earlier, it is not allowed to enter redundant or less than required parameters. So how are the optional parameters defined?
functions fn(s1:string,s2?:string):string{
return s1+' '+s2
}
It should be noted that optional parameters must be followed by required parameters. In other words, required parameters are not allowed after optional parameters
function buildName(firstName?: string, lastName: string) {
if (firstName) {
return firstName + ' ' + lastName;
} else {
return lastName;
}
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName(undefined, 'Tom');
// index.ts(1,40): error TS1016: A required parameter cannot follow an optional parameter.
default parameters
In ES6, we allow adding default parameters to function parameters, and TypeScript will recognize the added default parameters as optional parameters.
functions fn(firstName:string,lastName:string='tom'){
return firstName+' '+ lastName
}
fn('xiaoming','tools')
fn('yue')
At this time, it is not restricted by "optional parameters must be followed by required parameters"
functions fn(firstName:string='tom',lastName:string){
return firstName+' '+ lastName
}
fn('xiaoming','tools')
fn('yue')
remaining parameters
In ES6, you can use ...rest to get the remaining parameters (rest parameters) in the function
function push(s1,...rest){
rest.forEach(v=>s1.push(v));
}
let a:<Array>any = [];
push(a,1,2,3)
In fact, rest is an array. So we can define it with the type of the array
function push(array:any[],...rest:any[]){
rest.forEach(item=>array.push(item))
}
let a = [];
push(a, 1, 2, 3);
Note that the rest parameter can only be the last parameter.
overload
Overloading allows a function to accept different numbers or types of arguments and treat them differently
functions reverse(x:string|number):string|number|void{
if(typeof x === 'string'){
return x.split('').reverse().join('')
}else if(typeof x === 'number'){
return Number(x.toString().split('').reverse().join(''))
}
}
However, this has a disadvantage, that is, it cannot be expressed accurately. When the input is a number, the output should also be a number. When the input is a string, the output should also be a string.
At this point, we can use overloading to define multiple reverse
function types:
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
In the above example, we repeatedly defined the function multiple times reverse
, the first few times were function definitions, and the last time was function implementation. In the editor's code hints, the first two hints can be seen correctly.
Note that TypeScript will give priority to matching from the first function definition, so if multiple function definitions have an inclusion relationship, you need to write the precise definition first.
8. Type assertions
Type assertions (Type Assertion) can be used to manually specify the type of a value.
值 as 类型
or
<类型>值
The former must be used in tsx syntax (the ts version of React's jsx syntax), ie 值 as 类型
.
A syntax like this is represented in tsx ReactNode
, and in ts, in addition to representing a type assertion, it may also represent a generic type
值 as 类型
Therefore, it is recommended that you use this syntax uniformly when using type assertions .
let a:unknown;
a='xxxxx';
let b:string;
b= a as string;
interface Cat{
name:string,
run():void;
}
interface Fish{
name:string,
swim():viod;
}
function swim(animal:Cat|Fish){
if(typeof (anumal as Fish).swim === 'function'){
return true
}
return false
}
const cat:Cat={
name:"张三",
run(){
console.log('run')
}
}
swim(cat);
9. Built-in objects
There are many built-in objects in JavaScript, which can be used as defined types in TypeScript
A built-in object is an object that exists on the global scope according to a standard, here the standard refers to the standard of ECMAScript and other environments (Dom)
ECMAScript's built-in objects
The built-in objects provided by the ECMAScript standard are
Boolean
, Error
, Date
, RegExp
etc.
let b: Boolean = new Boolean(1);
let e: Error = new Error('Error occurred');
let d: Date = new Date();
let r: RegExp = /[a-z]/;
Built-in Objects for DOM and BOM
Document
, HTMLElement
, Event
, NodeList
etc.
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
// Do something
});
Their definition files are also in the definition file of the TypeScript core library .
in the definition file of the library.