目录
定义:typescript 是javascript类型的超级, 可以编译成纯javascript, ,可以跨浏览器,跨平台运行
数据类型
js基本数据类型:number string boolean undefined null symbol
js的引用数据类型: Object array function
ts定义数据类型
- 基本数据类型
let 变量名:数据类型 = 值
// 数据类型定义
let num:number = 100;
let str:string = 'hello'
let flag:boolean = true;
let timer:undefined = undefined;
let obj:null = null;
默认情况下null和undefined是所有类型的子类型 ; 就是说你可以把 null和undefined赋值给任何类型的变量
- 任意类型
使用 any 关键字 定义任意类型
let 变量名:any = value;
// 后期可以随便进行更改
- 函数的定义方式
- 函数的参数类型定义
function f(str:string, ...){
}
- 函数返回值的定义
// 函数存在返回值
function 函数名(参数名:参数类型):返回值的类型{
return value; // value 比如符合你定义的类型
}
// 函数没有返回值 使用void 关键字
function 函数名(参数名:参数类型):viod{
// 函数不需要返回值
}
// 如果函数的返回值是一个对象
function f(n:string, a:number):{name:string,age:number}{
return {name:n, age:a}
}
- ts的类型推论
TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型; 这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时。
let x = 100; // 这种情况下 ts 就会使用类型推论
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:
- 隐式任意类型
let str; // 通过类型推论 推断为 任意类型
str = 'hello';
str = 100;
- 联合类型
联合类型(Union Types)表示取值可以为多种类型中的一种。 使用 | 符号
let 变量名: 数据类型1 | 数据类型2 | ... = value ;// value 可以是 类型的任意一个; 后期可以更改为定义的类型中任意一个
- 定义数组
let 变量名:[number, string] = [1, '3'];
let 变量名:[number | string, string] = [1, '3'];
定义接口
定义接口: 通过 interface 关键字 ;
接口中的属性和对象的属性必须一一对应 ts 中定义接口 接口名字首字母大写
interface Person{
// 接口中的属性 自定义的, 定义属性时 需要确定 数据类型
name:string;
age:number;
sex:string
}
// 实现 接口 ; 对象中的属性,多一个或者少一个都不允许
let stu:Person = {
name:'张三',
age:18,
sex:'男',
// color:'黄色'
}
console.log(stu);
定义可选属性 通过 ? : 如果有一些属性是可有可无,可以定义为可选属性,通过 在属性名后边添加 ? 实现
interface Person{
name:string;
age:number;
sex?:string;
hariColor?:string
}
let stu:Person = {
name:'hello',
age:18,
sex:'nv',
hariColor:'123984'
}
定义任意属性 [propName:数据类型] :any
// 使用 [propName: string] 定义了任意属性取 string 类型的值。
// 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
interface Person{
// name:string;
name:number;
// [propName:string]:any // 属性名是任意的, 属性值 数据类型也是任意类型
[propName:string]:number //
}
let stu:Person = {
// name:'zs',
name:100,
// age:10,
// sex:'-23485'
// adfga:'aourtoiAJED'
afgd:238
}
定义只读属性 通过 readonly 关键字
interface Person {
readonly name:string;
age:number
}
// 只读 在该环节生效的
let stu:Person = {
name:'张三',
age:19
}
console.log(stu.name);
只读属性不允许更改
stu.name = '李四'
函数实现接口
interface Person {
name: string;
age: number
}
function Stu( a : Person){
console.log(a.name);
}
函数返回值 ,返回值是对象
interface Person {
name: string;
age: number
}
// 函数返回值 ,返回值是对象
function Stu(a:Person):{name:string, age:number}{
let newStu = {name:'张三', age:100}
if(a.name){
newStu.name = a.name;
}
if(a.age){
newStu.age = a.age;
}
return newStu
}
let res = Stu({name:'李四', age:18})
// let res = Stu({name:'', age:18})
console.log(res);
接口定义方法
interface Person {
name:string;
// say():void
say():number
}
let stu:Person = {
name:'张三',
say(){
console.log('hello');
return 100;
}
}
console.log(stu.say());
ts定义数组
// ts 定义数组:
// ========= 第一种形式 类型 + []
// 数组中的元素都是数值类型
let arr:number[] = [1,3,4,6554,67,3]
console.log(arr);
// =========== 元组: 限定数组中每个元素的类型 , 同时也限定了数组中元素的个数;
let arr2:[number, string] = [1, 'hello']
// =========== 第三种: 通过 数组的泛型 Array<数据类型>
let arr3:Array<number> = [21,4,45,23]
let arr4:Array<string> = ['ajds']
// ========= 通过接口定义数组 [index:number] 限定的是数组索引值的类型, 后边是限定数组中元素的类型
interface a{
// [index:number]:number
[index:number]:string
}
// let arr5:a = [1,4,5,6]
let arr5:a = ['234', '345', '35432']
// ========== 允许数组中出现任意值
let arr6:any[] = [23, '345', {name:'zadf'}]
定义函数
/*
js 的函数声明:
1. 函数声明式 : function fun(){}
2. 函数表达式 : let fun = function(){}
*/
// 函数声明式
function fun(a:number, b:number){
}
let fun2 = function(a:number, b:number){
}
// 限定返回值
function fun(a:number):number{
return a + 100;
}
let fun2 = function(b:number):number{
return b;
}
// 书写函数的完整格式 : 针对的是函数表达式的方式
// 定义函数时的变量名可以不同,但是数据类型必须一致
// 区分 => 和 es6 的箭头函数
let fun2:(x:number, y:number) => number = function(a:number, b:number):number{
return a + b;
}
let fun2:(x:number, y:number) => number = (a:number, b:number):number => a + b;
// 函数也存在类型推断
let myAdd: (baseValue: number, increment: number) => number =
function(x, y) { return x + y; };
// 可选参数 ?
let myAdd: (baseValue: number, increment?: number) => number = function(x, y) {
if(y){
return x + y;
}else{
return x;
}
};
// let res = myAdd(10)
let res = myAdd(10, 34)
console.log(res);
// 带默认值的参数 一旦指定了默认值,一般情况下默认值都作为最后一个参数使用
let sum:(a:number, b:number) => string = function(x:number, y = 100):string{
return x + y + 'hello';
}
console.log(sum(10, 20));
// 错误的
// let sum:(a:number, b:number) => string = function(x=100, y:number):string{
// return x + y + 'hello';
// }
// console.log(sum( 20));
// 可选参数和默认值 可以认为是等效的 如果使用了默认值,则认为该参数是可选的
// 剩余参数 我们可能不确定参数个数: 这个时候可以使用剩余参数 (rest参数) ...args
function fun(a:number, b:number, ...args:number[]){
console.log(a, b, args);
}
fun(1, 3, 123, 3245, 35)
函数重载
//1 定义重载函数的类型 : 定义的是函数类型
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
// 2 定义函数 !!!!!!!!!!!!!!!! 函数类型定义和函数定义之间不能 存在任何代码
function pickCard(x:any):any{
if(typeof x == 'object'){
return 100;
}else if(typeof x == 'number'){
return {suit:'hello', card:100}
}
}
console.log(pickCard(100));
console.log(pickCard([{suit:'213423', card:100}]));
枚举
定于枚举类型: 使用枚举我们可以定义一些带名字的常量。 使用枚举可以清晰地表达意图或创建一组有区别的用例。TypeScript支持数字的和基于字符串的枚举。
1. 数字类型的枚举
一旦定义枚举类型 : 数字类型的枚举,会存在默认值,默认值从0开始 ; 默认值会依次递增
enum E{
// 随意自定义 ; 自定义的是常量的名字,而没有给常量赋值,常量的默认是从0开始的
a,
b,
c
}
console.log(E.a,E.b,E.c); //0 1 2
//E[0] 这是通过枚举类型的值 获取枚举类型的名字
// []中的数字是 枚举类型的值; 而不是索引值
console.log(E[0],E[1],E[2]); //a b c
1.1.手动指定枚举类型的值
enum A {
a, // 第一个枚举名没有指定值,则默认是从0开始
b=10, // 指定了值,则使用指定的值
c // 没有指定值,会从上一个枚举值自动递增
}
console.log(A.a,A.b,A.c); // 0 10 11
console.log(A[0],A[10]); // a b
2.字符串类型枚举
enum C {
a="hello",
b="dd",
c="qwe"
}
console.log(C.a,C.b);
计算得到的枚举值:只能用于数字类型的枚举,不能用于字符串类型的枚举
enum e {
a=100,
b=200,
c=a+b,
d=a|b
}
console.log(e.d);
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
泛型: <自定义的的值> 代表数据类型,后期由你传入的类型决定 比如:
function f<M>(arg:M):M{
//
return arg;
}
f<string>('hello')