Typescript

本文详细介绍了 TypeScript 的基本类型如 any、string、number、元组、void 等,以及变量、数组、函数、类型断言、类型推断、位运算符、类型运算符等概念。还涵盖了循环结构、函数定义、类和接口、模块、命名空间、对象和数组操作,以及 TypeScript 中的高级特性,如泛型、装饰器和模块。
摘要由CSDN通过智能技术生成

https://m.runoob.com/typescript/ts-type.html

  1. any 定义变量可以是任意类型
  2. String 单引号,双引号表示字符串类型,let words: string = 您好,今年是 ${ name } 发布 ${ years + 1} 周年; 反引号定义多行文本或内嵌表达式
  3. 数组 let arr: number[] = [1,2]; let arr:Array = [1,2]
  4. Number 双精度64位浮点值,也可以表示整数和分数
  5. 元组:表示已知元素数量和类型,let x:[String,number] 各元素类型不必相同,但是赋值时,位置和类型必需相同,下标从0开始
  6. Void 用户标识方法返回值的类型,表示该方法没有返回值
  7. Null 表示对象值缺失
  8. Undefined 用于初始化变量为一个未定义的值
  9. Never 是其他类型包括(null和undefined)的子类型,代表从不会出现的值

变量不要使用 name 否则会与 DOM 中的全局 window 对象下的 name 属性出现了重名

TypeScript 遵循强类型,如果将不同的类型赋值给变量会编译错误

**类型断言(Type Assertion):**类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型
语法格式:<类型>值 或。值 as 类型

类型推断

变量作用域
全局变量:定义在程序结构的外部,可以在代码任何位置使用
类作用域: 定义在类里头,,但在类方法外,类对象访问,或者静态变量,类名直接访问
局部作用域:局部变量,在方法块中使用

位运算符
位操作是程序设计中对位模式按位或二进制数的一元和二元操作

类型运算符
typeof 运算符
typeof 是一元运算符,返回操作数的数据类型。
var num = 12
console.log(typeof num); //输出结果: number

负号运算符(-)
var x:number = 4
var y = -x;
console.log("x 值为: ",x); // 输出结果 4
console.log("y 值为: ",y); // 输出结果 -4

switch…case 语句
switch(expression){
case constant-expression :
statement(s);
break; /* 可选的 /
case constant-expression :
statement(s);
break; /
可选的 */

/* 您可以有任意数量的 case 语句 */
default : /* 可选的 */
   statement(s);

}
switch 语句中的 expression 是一个常量表达式,必须是一个整型或枚举类型
不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止
default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的

for 循环
for ( init; condition; increment ){
statement(s);
}
init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可
在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可

for…in 循环
for (var val in list) {
//语句
}
val 需要为 string 或 any 类型

for…of 、forEach、every 和 some 循环
let someArray = [1, “string”, false];
for (let entry of someArray) {
console.log(entry); // 1, “string”, false
}

let list = [4, 5, 6];
list.forEach((val, idx, array) => {
// val: 当前值
// idx:当前index
// array: Array
});

let list = [4, 5, 6];
list.every((val, idx, array) => {
// val: 当前值
// idx:当前index
// array: Array
return true; // Continues
// Return false will quit the iteration
});

while 循环
var num:number = 5;
var factorial:number = 1;

while(num >=1) {
factorial = factorial * num;
num–;
}
console.log(“5 的阶乘为:”+factorial);

do…while 循环
do
{
statement(s);
}while( condition );
请注意,条件表达式出现在循环的尾部,所以循环中的 statement(s) 会在条件被测试之前至少执行一次

无限循环
无限循环就是一直在运行不会停止的循环。 for 和 while 循环都可以创建无限循环
for(;😉 {
console.log(“这段代码会不停的执行”)
}

while(true) {
console.log(“这段代码会不停的执行”)
}

函数定义
函数只有通过调用才可以执行函数内的代码
function test() { // 函数定义
console.log(“调用函数”)
}
test() // 调用函数

函数返回值
function function_name():return_type {
// 语句
return value;
}
return_type 是返回值的类型
返回值的类型需要与函数定义的返回类型(return_type)一致

带参数函数
function func_name( param1 [:datatype], param2 [:datatype]) {
}
param1、param2 为参数名
datatype 为参数类型
function add(x: number, y: number): number {
return x + y;
}
console.log(add(1,2))

可选参数和默认参数
在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 ?
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
let result1 = buildName(“Bob”); // 正确
let result2 = buildName(“Bob”, “Adams”, “Sr.”); // 错误,参数太多了
let result3 = buildName(“Bob”, “Adams”); // 正确

默认参数
function function_name(param1[:type],param2[:type] = default_value) {
}
function calculate_discount(price:number,rate:number = 0.50) {
var discount = price * rate;
console.log("计算结果: ",discount);
}
calculate_discount(1000)
calculate_discount(1000,0.30)

剩余参数
有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义,剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入
function buildName(firstName: string, …restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName(“Joseph”, “Samuel”, “Lucas”, “MacKinzie”);
函数的最后一个命名参数 restOfName 以 … 为前缀,它将成为一个由剩余参数组成的数组,索引值从0(包括)到 restOfName.length(不包括)
function addNumbers(…nums:number[]) {
var i;
var sum:number = 0;

for(i = 0;i<nums.length;i++) { 
   sum = sum + nums[i]; 
} 
console.log("和为:",sum) 

}
addNumbers(1,2,3)
addNumbers(10,10,10,10,10)

匿名函数
匿名函数是一个没有函数名的函数,匿名函数在程序运行时动态声明,除了没有函数名外,其他的与标准函数一样,我们可以将匿名函数赋值给一个变量,这种表达式就成为函数表达式
var res = function( [arguments] ) { … }
var msg = function() {
return “hello world”;
}
console.log(msg())

匿名函数自调用
匿名函数自调用在函数后使用 () 即可
(function () {
var x = “Hello!!”;
console.log(x)
})()

构造函数
TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数
var res = new Function ([arg1[, arg2[, …argN]],] functionBody)
arg1, arg2, … argN:参数列表。
functionBody:一个含有包括函数定义的 JavaScript 语句的字符串
var myFunction = new Function(“a”, “b”, “return a * b”);
var x = myFunction(4, 3);
console.log(x);
—结果:12

递归函数
递归函数即在函数内调用函数本身
function factorial(number) {
if (number <= 0) { // 停止执行
return 1;
} else {
return (number * factorial(number - 1)); // 调用自身
}
};
console.log(factorial(6)); // 输出 720
结果:65432=720

Lambda 函数
Lambda 函数也称之为箭头函数,箭头函数表达式的语法比函数表达式更短,函数只有一行语句
( [param1, parma2,…param n] )=>statement;
var foo = (x:number)=>10 + x
console.log(foo(100)) //输出结果为 110

我们可以不指定函数的参数类型,通过函数内来推断参数类型
var func = (x)=> {
if(typeof x==“number”) {
console.log(x+" 是一个数字")
} else if(typeof x==“string”) {
console.log(x+" 是一个字符串")
}
}
func(12)
func(“Tom”)

函数重载
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表
参数类型不同:
function disp(string):void;
function disp(number):void;
参数数量不同:
function disp(n1:number):void;
function disp(x:number,y:number):void;
数类型顺序不同:
function disp(n1:number,s1:string):void;
function disp(s:string,n:number):void;
实例:
function disp(s1:string):void;
function disp(n1:number,s1:string):void;

function disp(x:any,y?:any):void {
console.log(x);
console.log(y);
}
disp(“abc”)
disp(1,“xyz”);
结果为:
abc
undefined
1
xyz

Number 对象属性

String 对象属性

Array(数组)
var array_name[:datatype]; //声明
array_name = [val1,val2,valn…] //初始化

var array_name[:datatype] = [val1,val2…valn]

Array 对象
var arr_names:number[] = new Array(4)
for(var i = 0; i<arr_names.length; i++) {
arr_names[i] = i * 2
console.log(arr_names[i])
}

var sites:string[] = new Array(“Google”,“Runoob”,“Taobao”,“Facebook”)
for(var i = 0;i<sites.length;i++) {
console.log(sites[i])
}

数组解构
我们也可以把数组元素赋值给变量
var arr:number[] = [12,13]
var[x,y] = arr // 将数组的两个元素赋值给变量 x 和 y
console.log(x)
console.log(y)

数组迭代
我们可以使用 for 语句来循环输出数组的各个元素
var j:any;
var nums:number[] = [1001,1002,1003,1004]
for(j in nums) {
console.log(nums[j])
}

多维数组
一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array)
ar arr_name:datatype[][]=[ [val1,val2,val3],[v1,v2,v3] ]
实例:
var multi:number[][] = [[1,2,3],[23,24,25]]
console.log(multi[0][0])
console.log(multi[0][1])
console.log(multi[0][2])
console.log(multi[1][0])
console.log(multi[1][1])
console.log(multi[1][2])

元组
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组,元组中允许存储不同类型的元素,元组可以作为参数传递给函数
格式:
var tuple_name = [value1,value2,value3,…value n]
实例:
var mytuple = [10,“Runoob”];
访问元组
uple_name[index]
元组运算
push() 向元组添加元素,添加在最后面
pop() 从元组中移除元素(最后一个),并返回移除的元素
更新元组
解构元组

联合类型
联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值
注意:只能赋值指定的类型,如果赋值其它类型就会报错
格式:Type1|Type2|Type3
实例:
var val:string|number
val = 12
console.log("数字为 "+ val)
val = “Runoob”
console.log("字符串为 " + val)
返回值:
数字为 12
字符串为 Runoob

联合类型数组

接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法
注意:接口不能转换为 JavaScript。 它只是 TypeScript 的一部分
定义:
interface interface_name {
}
实例:
interface IPerson {
firstName:string,
lastName:string,
sayHi: ()=>string
}

var customer:IPerson = {
firstName:“Tom”,
lastName:“Hanks”,
sayHi: ():string =>{return “Hi there”}
}

console.log("Customer 对象 ")
console.log(customer.firstName)
console.log(customer.lastName)
console.log(customer.sayHi())

联合类型和接口

接口和数组
接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串
实例:
interface namelist {
[index:number]:string
}
// 类型一致,正确
var list2:namelist = [“Google”,“Runoob”,“Taobao”]
// 错误元素 1 不是 string 类型
// var list2:namelist = [“Runoob”,1,“Taobao”]

接口继承
Child_interface_name extends super_interface_name
Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name
单继承实例:
interface Person {
age:number
}

interface Musician extends Person {
instrument:string
}

var drummer = {};
drummer.age = 27
drummer.instrument = “Drums”
console.log("年龄: "+drummer.age)
console.log("喜欢的乐器: "+drummer.instrument)

多继承实例
interface IParent1 {
v1:number
}

interface IParent2 {
v2:number
}

interface Child extends IParent1, IParent2 { }
var Iobj:Child = { v1:12, v2:23}
console.log("value 1: “+Iobj.v1+” value 2: "+Iobj.v2)

TypeScript 类
格式:
class Person {
}
创建实例化对象
var object_name = new class_name([ arguments ])
类的继承
TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)
格式:
class child_class_name extends parent_class_name
继承类的方法重写
static 关键字
instanceof 运算符
访问控制修饰符
类和接口

TypeScript 对象

TypeScript 命名空间
命名空间一个最明确的目的就是解决重名问题。
假设这样一种情况,当一个班上有两个名叫小明的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的姓(王小明,李小明),或者他们父母的名字等等。
命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。
TypeScript 中命名空间使用 namespace 来定义,语法格式如下:
namespace SomeNameSpaceName {
export interface ISomeInterfaceName { }
export class SomeClassName { }
}
以上定义了一个命名空间 SomeNameSpaceName,如果我们需要在外部可以调用 SomeNameSpaceName 中的类和接口,则需要在类和接口添加 export 关键字
要在另外一个命名空间调用语法格式为:
SomeNameSpaceName.SomeClassName;

如果一个命名空间在一个单独的 TypeScript 文件中,则应使用三斜杠 /// 引用它,语法格式如下:
///

嵌套命名空间
命名空间支持嵌套,即你可以将命名空间定义在另外一个命名空间里头

TypeScript 模块
TypeScript 模块的设计理念是可以更换的组织代码。
模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。
两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。
模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。 大家最熟知的JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js。
此外还有有 SystemJs 和 Webpack。
模块导出使用关键字 export 关键字,语法格式如下:
// 文件名 : SomeInterface.ts
export interface SomeInterface {
// 代码部分
}

要在另外一个文件使用该模块就需要使用 import 关键字来导入:
import someInterfaceRef = require(“./SomeInterface”);

TypeScript 声明文件

TypeScript Map 对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值