let a:number = 10;
let b:string = '测试';
let c:boolean = true;
let d:null = null;
let a:undefind= undefind;
let a:number[ ]=[ 1,1,1,1 ];
let a:string[ ] =[ 's','s','s' ];
let c:boolean [ ]=[ false,true ];
let a:(string|number)[ ] = [ 1,'s',1,'s' ];
let a:string|number[ ] = '可以是字符串或者数组';
let a:string|number[ ] = [ 13,14 ];
type custom = (number|string)[ ];
let a:custom =[1,'s',1,'s'];
1、指定 参数和返回值 的类型
function add(num1:number,num2:number):number{
return num1+num2;
}
// 规定只能传入 数字类型 并且返回参数为数字类型的值
console.log(add(1,2)); // 3
2、箭头函数写法
const add:(num1:number,num2:number)=>number= (num1,num2)=>{
return num1+num2;
}
3、void 类型 函数没有返回值 那么返回值
funciton greet(name:string):void{
console.log(name);
}
function processArray(arr: (string | number)[]): void {
// 在此处编写处理数组的逻辑
}
4、 函数类型 可选参数 在可传可不传参数名称后面加 ?
// 注意:可选参数只能出现在必填参数后面,不能出现在必填参数前面
function myslice(start:number,end?:number):void{
console.log(start,end);
}
let obj:{
name:string;
age:number; // 分号隔开
sayHi(age:number):void;
}={
name:'jack',
age:19,
sayHi(age){
console.log(age);
}
}
let obj:{
name:string;
age:number;
sayHi:(age:number)=>void; // 也可以这样写
}={
name:'jack',
age:19,
sayHi:(age)=>{
console.log(age);
}
}
```cpp
let obj:{
name?:string;
age:number;
sayHi:(age:number)=>void;
}={
age:19,
sayHi(age){
console.log(age);
}
}
function myAxios(config:{url:string;method?:sting}):void{
console.log(config);
}
myAxios({
url:'https://xxxx.com'
})
// 当一个对象类型 多次被使用 一般会使用接口 interface来描述对象类型 达到复用
// 没有分号隔开
interface IPerson {
name:string
age:number
sayHi():void
}
let person:IPerson={
name:'jack',
age:12,
sayHi(){
}
}
// 接口interface 和 type 类型别名 的对比
// 相同点: 都可以给对象指定类型
// 不同点: 接口,只能为对象指定类型;类型别名,可以为任意类型指定别名
interface IPerson {
name:string
age:number
sayHi():void
}
type IPerson = {
name:string
age:number
sayHi():void
}
type NumStr = number | string
interface point2d {
x:number
y:number
}
interface point3d {
x:number
y:number
z:number
}
point3d跟point2d有公共部分
那可以写成
interface point3d extends point2d {
z:number
}
使用场景:
1、在地图中,使用经纬度来标记位置信息
let position:number[ ]=[ 39,116 ]
这种写法缺点是不够严谨,该类型数组中可以出现多个任意的数字
更好的方法是使用元组 Tuple
let position:[number,number]=[39,116]
元组就是确切说明有多少个元素,以及元素类型
在 TS 中,某些没有明确指出类型的地方,TS 的类型推论机制会帮助提供类型,换句话说:由于类型推论的存在,这些地方,类型注解可以省略不写!
发生类型推论的2 种常见场景:
1 声明变量并初始化时
2 决定函数返回值时
1 、 let age =18; ts自动判断类型为number 那就不用写
2 、 function add(num1:number,num2:number) {
return num1+num2;
}
ts自动判断函数返回类型为number 那就不用写函数返回
<a href="http://www.com" id="link">链接</a>
const aLink = document.getElementById('link') as HTMLAnchorElement;
技巧:在控制台,console.dir()打印DOM元素 ,属性列表最后面即可看到该元素类型
还有一种不常用的写法,知道即可
const aLink =<HTMLAnchorElement>document.getElementById('link') ;
let str1 = '测试';
const str2 = '测试';
str1 使用 let 定义的 所以是 string类型
str2 使用const定义的 所以类型就是 '测试' ,也就是一个字面量类型
let age:18=18; 这样写 age类型就是18 age不能赋值等于其他
let name:'jack'='jack';
使用场景举例:(用来表示一组明确的可选值列表)
定义一个函数 控制游戏方向
function changeDirection (direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
相比于 direction:string, 字面量写法更加的精确、严谨
约定枚举名称、枚举中的值 以大写字母开头
enum Direction { Up , Down , Left , Right }
function changeDirection (direction:Direction ){
console.log(direction)
}
解释:
使用enum关键字定义
约定枚举名称、枚举中的值 以大写字母开头
多个值直接逗号隔开
定义好后,直接使用枚举名称作为注解
使用
changeDirection (Direction.Up)
实参的值就是枚举Direction 成员的任意一个,可以用对象的方法拿到
问题 :我们把枚举成员 作为函数实参 那他的值是什么
Direction.Up=0 默认的
枚举成员是有值的 默认从零开始自增长
我们把成员值为数字的枚举称为 数字枚举
当然也可以初始化默认值
enum Direction { Up=18 , Down=4 , Left=5 , Right=1 }
enum Direction { Up=5 , Down , Left , Right } 这样 Down为6 Left为7 Right为8
enum Direction { Up=5 , Down , Left , Right=1 } 这样 Down为6 Left为7 Right为1
字符串枚举
enum Direction { Up='up', Down='down' , Left='left' , Right='right' }
注意:字符串没有自增长行为 因此每个成员都必须有初始值
一般不推荐使用 any
any 代表该值可以为任意值 随意操作 不会有代码提示
let a:any = 12;
a='测试';
function add(num:any):any{
return 'ssss'
}
add('随缘')
除非临时使用any来避免书写很长、很复杂的类型 不然不推荐使用
可以在类型上下文中引用变量或者属性的类型
根据已经有的变量的值,获取该值的属性类型,来简化类型书写
let p ={x:1,y:2};
interface obj {
x:number
y:number
}
function add (point:obj):void {}
add(p)
简写
let p ={x:1,y:2};
function add(point:typeof p):void{ } 那么add接收参数类型就跟p一样 也是数字类型的对象
add({x:2,y3})
let num:typeof p.x;
typeof只能查询变量或者属性的类型,无法查询其他形式的类型(比如,函数调用的类型)
class类
class Person { }
const p = new Person ( ) ; 那么 p 相当于 const p:Person;
class Person2 {
age:number
name:string='jack'
gender='男'
}
const p2 = new Person2 ( ) ;
p.name
没有初始值 要声明 类型
有初始值 可以不用
class Person3 {
age:number
name:string
constructor(age:number,name:string) {
this.age = age;
this.name = name;
}
}
const p3 = new Person3 (18,'jack') ; 必须有初始值
成员初始化后,才可以通过this.age来访问
需要为构造函数指定注解类型,否则会被隐式推断为any,构造函数不需要返回值类型
class Point {
x=10
y=10
scale (n:number):void {
this.x*=n
this.y*=n
}
}
const p4= new Point () ;
p4.scale(10);
console.log(p.x,p.y)
extends 继承父类 implements 实现接口
class Animal {
move ( ){ console.log('Moving') }
}
class Dog extends Animal {
bark ( ){ console.log( '汪' ) }
}
const dog = new Dog( )
dog.move( )
dog.bark( )
implements 接口
interface Singable {
name:string
sing():void
}
class Person implements Singable {
name='jack'
sing( ){
console.log('弟弟')
}
}
class 拥有的特点 public 公有的 protected 受保护的 private 私有的
class Animal {
public move( ) {
console.log('谁都可以访问,public是默认的,一般都是省略')
}
protected again ( ){
console.log('受保护的,只对其声明所在类和子类中可见')
console.log('只能通过this来访问')
}
private myself( ){
console.log('私有的,只有自己可见')
}
}
class Dog extends Animal{
bark( ) {
this.again( )
console.log('只能通过this来访问受保护的')
}
}
const a = new Animal ();
const b = new Dog ();
a.move( );
b.again() 报错
还有 readonly 只读 防止在构造函数之外对属性进行赋值
class Person {
readonly age:number==18
constructor (age:number){
this.age=age 报错 不能更改
}
setAge ( ){
}
}
interface IPerson {
readonly name:string
}
let obj:IPerson = {
name:'jack'
}
obj.name = 'ssss' 报错
class Point {
x:number
y:number
}
class Point2d{
x:number
y:number
}
const p:Point = new Point2d( )
参数少的兼容参数多的,成员多的可以赋值给少的
class Ap {
x:number
y:number
}
class Ab{
x:number
y:number
z:number
}
const p:Ap = new Ab( )
接口interface也类似、并且接口跟class类也互相兼容
函数兼容性:考虑参数个数、参数类型、返回值类型
参数个数:参数多的兼容参数少的,也就是参数少的可以给参数多的赋值
type F1 = (a:number)=>void
type F2 = (a:number,b:number)=>void
let f1:F1
let f2:F2 = f1
返回值的兼容
type F5 = ()=>string
type F6 = ()=>string
let f5:F5
let f6:F6=f5
返回值是原始类型,那么两个类型需要相同
type F7 = ()=>{ name:string }
type F8 = ()=>{ name:string,age:number }
let f7:F7
let f8:F8
f7 = f8
f8=f7 错误示例
返回值是对象类型的,成员多的可以赋值给成员少的,不能返过来