【TS学习和在react中的简单应用】

1. ts基础

1.1 ts基本类型

//js原始类型:number/string/boolean/null/undefined/symbol
//ts新增any-任意类型

//1-
var name:string | number;
//string或是number类型 
//多种数据类型中的一种,TS中称为联合类型

//2-类型别名
type mytype = string | number;
let age:mytype = 10;

1.2 数组

//1-已知数组的长度和类型:在TS中称为元组类型

  //表示数组的每一项都是字符串,长度不固定
  var arr1:string[] = ['1','2'];

  //表示数组的每一项都是字符串或者数字,长度不固定
  var arr2:(string | number)[] = [1,'2'];
  var arr3:Array<string | number> = [1,'2'];

//2-表示数组只能是两项,第一项是字符串,第二项是数字,不能多,不能少
  var arr: [string, number] = ['lala', 10]

1.3 对象

// 1- 对象类型
type o = {a:number,cb():void,list?:string[],[propName:string]:any}
let obj:o = {
  a:0,
  cb() {},
  list:['1']
}


// 2- interface-在TS中称为接口,用来描述对象的形状

//表示必须有name是字符串类型,age是数字类型两个属性
//loaction属性中的“?”表示可有可无
//[propName:string]:any 可以有任意类型的属性
interface IObj {
  name:string,
  age:number,
  location?:string,
  // [propName:string]:any
}
var obj1:IObj = {
  name:'lala',
  age:10,
  location:'1'
}
var obj1:IObj = {
  name:'lala',
  age:10,
}
var obj1:IObj = {
  name:'lala',
  age:10,
  // a:1
}

//3-接口继承:如果两个接口有相同的属性方法时使用继承来实现复用
  interface A {
    a:string
  }
  interface B {
    b:number
  }
  
  interface AB extends A,B{
    ab:()=>void
  }

  let obj2:AB = {
    a:'111',
    b:222,
    ab(){}
  }

//4-对比:interface(接口)与type(类型别名)

  //相同:都可以给对象指定类型

  //不同:interface只能为对象指定类型,type可以为任意类型指定别名
  
export default {}

1.4 函数

//1-
  //指定a,b形参类型分别为字符串和数字,必须有返回值,返回值类型为布尔和数字
  //c旁的?表示这个参数可有可无
  //没有返回值类型为void

  // function fun1(a:string,b:number,c?:string):boolean | number{
  //   return b;
  // };

  // let fun1 =(a:string,b:number,c?:string):boolean | number =>{
  //   return b;
  // };

  let fun1:(a:string,b:number,c?:string) => boolean | number = (a,b,c) => {
    return b;
  };

  // var myname:number = fun1('1',1) //不能将boolean | number的值赋值给数字类型的myname
  fun1('1',2);
  fun1('1',2,'3');

//2-
interface IFun{
  (a:string,b:number,c?:string):boolean | number
};
var fun2:IFun = fun1;

//3-
interface Iobj{
  name:string,
  age:number,
  getInfo?:(name:string)=>string
}

var obj:Iobj = {
  name:'lala',
  age:2,
  getInfo:(name:string)=>name
}

1.5 class类

//1-
  class Bus{
    public name = 'lala';
    private _list:any = [];
    protected age = 10;

    subscribe(cb:any){
      this._list.push(cb);
    };
    dispatch(){
      this._list.forEach((cb:any )=> {
        cb&&cb();
      });
    }
  }
  class Child extends Bus{
    getInfo(){
      // console.log(this.name,this._list,this.age) //_list私有属性访问不到
    }
  }

  var obj = new Bus();
  // console.log(obj.name,obj._list,obj.age) //_list私有属性和age受保护属性访问不到


//2-
//该接口表示至少要有getName属性

// interface Ifun1{
//   getName:()=>string,
// }

interface Ifun1{
  getName():string      
}

class A implements Ifun1{
  a1(){

  }
  a2(){

  }
  getName(){
    return 'AAA'
  }
}
class B implements Ifun1{
  b1(){

  }
  b2(){

  }
  getName(){
    return 'BBB'
  }
}

function init(obj:Ifun1){
  obj.getName();
}

var objA = new A();
var objB = new B();

init(objA);
init(objB);

console.log(objA)

//-3 接口还可以通过extends 继承
interface IFun2 extends Ifun1{
  allInfo:{name:string}
}

class C implements IFun2{
  allInfo = { name:'lala' };
  getName = ()=> 'CCC'

}

1.6 枚举enum

TS-枚举类型enum

1.7 typeof

let obj1 = {
  name:'lala',
  age:19,
}

let obj2:(typeof obj1) = {
  name:'xiaoming',
  age:10,
}

1.8 TS中的泛型

TS中的泛型

//TS中的泛型 https://blog.csdn.net/weixin_44761091/article/details/124017662
//1. 泛型用法------------------------------------------------------------------------------------------
//1.1 在函数中使用泛型
  function test <T> (arg:T):T{
    console.log(arg);
    return arg;
  }
  test<number>(111);// 返回值是number类型的 111
  test<string | boolean>('hahaha')//返回值是string类型的 hahaha
  test<string | boolean>(true);//返回值是布尔类型的 true


//1.2 在接口中使用泛型
  interface Search {
    <T,Y>(name:T,age:Y):T
  }

  let fn:Search = function <T, Y>(name: T, id:Y):T {
    console.log(name, id)
    return name;
  }
  fn('li',11);//编译器会自动识别传入的参数,将传入的参数的类型认为是泛型指定的类型

//1.3 在类中使用泛型
  class Animal<T> {
    name:T;
    constructor(name: T){
    this.name = name;
    }
    action<T>(say:T) {
      console.log(say)
    }
  }
  let cat = new Animal('cat');
  cat.action('mimi')
 
 //2. 泛型约束-------------------------------------------------------------------------------------------------
 //2.1 使用接口约束泛型
  interface Person {
    name:string;
    age:number;
  }
  function student<T extends Person>(arg:T):T {
    return arg;
  }

  // student({name:'lili'});//报错:类型 "{ name: string; }" 中缺少属性 "age",但类型 "Person" 中需要该属性
  // student({ name: "lili" , age:'11'});//报错不能将类型“string”分配给类型“number”
  student({ name: "lili" , age:11});

//2.2 数组泛型
  let arr:Array<number> =[1,2,3]
  // let arr:number[]=[1,2,3]

//3. 泛型工具类型--------------------------------------------------------------------------------------------------
//3.1 Partial
//partial<T>的作用就是将某个类型中的属性全部变为可选项?
  interface Person {
    name:string;
    age:number;
  }
  function person<T extends Person>(arg: Partial<T>):Partial<T> {
    return arg;
  }
  person({name:'hua'})
  person({age:0})
  person({})

//3.2 Record
//type Record<K extends keyof any, T>的作用是将中的类型转换对象属性,T转为对象的属性值
//https://blog.csdn.net/qq_36503569/article/details/119383782
  type key ='home'|'about'|'other';

  interface value {
    title:string
  }

const data:Record<key,value> = {
  home:{title:'home'},
  about:{title:'about'},
  other:{title:'other'},
}

let a:{[propName:symbol]:string} = {};
let name1 = Symbol('name');
let name2 = Symbol('name')
// a.name = 'lili';//报错不能ongoing.访问
a[name1] = 'lucy';
// console.log(a);//{Symbol(name1): 'lucy'}
// console.log(a[name1]);//lucy
// console.log(name1 === name2)//false

let title1 = Symbol.for("天天向上");
let title2 = Symbol.for("天天向上");
// console.log(title1,title2)//Symbol(天天向上)
// console.log(title1 === title2)//true
// console.log(Symbol.keyFor(title1)); // 天天向上


// console.log(Reflect.ownKeys(a))//[Symbol(name)]
// console.log(Reflect.ownKeys([]))//['length']
// console.log(Reflect.ownKeys(['w']))//['0', 'length']

//3.3 Pick
// Pick<T, K>
// K应为“keyof T”中的所包含的子类型
interface Todo {
  title:string,
  desc:string,
  time:string
}
//表示对象必须有且只有title和time两个属性类型
//K不能为'title'|'time'|'a',eyof T中不含a类型
type TodoPreview = Pick<Todo, 'title'|'time'>;
const todo: TodoPreview ={
  title:'吃饭',
  time:'明天',
}

//3.4 Exclude
// Exclude<T,U>的作用是将某个类型中属于另一个类型的属性移除掉
type T0 = Exclude<"a" | "b" | "c", "a">; // 去除"a",得到b" | "c"
const t:T0 ='b';

//2.5 ReturnType
// returnType<T>的作用是用于获取函数T的返回类型
type T00 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<<T>() => T>; // {}
type T3 = ReturnType<<T extends U, U extends number[]>() => T>; // number[]
type T4 = ReturnType<any>; // any
type T5 = ReturnType<never>; // any
// type T6 = ReturnType<string>; // 报错
// type T7 = ReturnType<Function>; // 报错

2. class+ts

2.1 state

import React, { Component,createRef } from 'react'

interface iState {
  text:string,
  // list:string[]
  list:Array<string>
}
export default class App extends Component<any,iState> {//<约定属性,约定状态>
  state ={
    text:'',
    list:[]
  }

  //HTMLInputElement指定input元素类型
  //HTMLDivElement指div元素类型

  myref = createRef<HTMLInputElement>();
  render() {
    return (
      <div>
        {/* <input type="text" value={this.state.text} onChange={
          (e)=>{
            this.setState({text:e.target.value})
          }
        }/>
        {this.state.text} */}

        <input ref={this.myref}/>
        <button onClick={()=>{
           // as是断言的一种方式,我断定这个类型是什么
           //as any也不会报错
          console.log((this.myref.current as HTMLInputElement).value)
          this.setState({
            text:(this.myref.current as HTMLInputElement).value,
            list:[...this.state.list,(this.myref.current as HTMLInputElement).value]
          });
        }}>点我{this.state.text}-{this.state.list.toString()}</button>
      </div>
    )
  }
}

2.2 props

import React, { Component } from 'react'

export default class App extends Component{
  state = {
    show:false
  }
  render() {
    return (
      <div>
        app
        <Navbar title="首页" cb={()=>{
          this.setState({show:!this.state.show})
        }}/>
        {this.state.show && <Sidebar/>}
      </div>
    )
  }
}

interface iProps {
  title?:string,
  cb:()=>void
}
class Navbar extends Component<iProps,any> {
  render(){
    return (
      <div>
        Navbar-{this.props.title}
        <button onClick={()=>{
          this.props.cb();
        }}>add</button>

      </div>
    )
  }
}

class Sidebar extends Component {
  render(){
    return (
      <div>
        Sidebar
      </div>
    )
  }
}

3. function+ts

3.1 state

import React,{useState,useRef} from 'react'

export default function App() {
  const [name] = useState<string>('lala');
  const [list,setList] = useState<string[]>([]);

  const myref = useRef<HTMLInputElement>(null);
  return (
    <div>
      name-{name}
      <input ref={myref} />
      <button onClick={()=>{
        console.log((myref.current as HTMLInputElement).value)
        setList([...list,(myref.current as HTMLInputElement).value])
      }}>add</button>
      {list.toString()}
    </div>
  )
}

3.2 props

import React,{useState} from 'react'

export default function App() {
  const [show,setShow] = useState(false);
  return (
    <div>
      <Navbar title="lala" cb={()=>{
        setShow(!show)
      }} a="1"/>
      {show && <Sidebar/>}
    </div>
  )
}

interface iProps {
  title?:string,
  cb():void,
  [propName:string]:any
}

// function Navbar (props:iProps){
//   return (
//     <div>
//       Navbar-{props.title}
//       <button onClick={()=>{
//         props.cb();
//       }}>add</button>
//     </div>
//   )
// }

const Navbar:React.FC<iProps> = (props)=>{
  return (
    <div>
      Navbar-{props.title}
      <button onClick={()=>{
        props.cb();
      }}>add</button>
    </div>
  )
}

function Sidebar(){
  return <div>Sidebar</div>
}

4. router

类型RouteComponentProps防止props中history报错

import React, { Component } from 'react'
import axios from 'axios'
import { RouteComponentProps } from 'react-router-dom'

interface IItem {
  filmId:number,
  name:string
}
//类型RouteComponentProps防止props中history报错
export default class Film extends Component<RouteComponentProps,any> {
  state ={
    list:[]
  }
  componentDidMount(): void {
    axios({
      url:"https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=9261499",
      method:'get',
      headers:{
        'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16745641013679850669801473","bc":"110100"}',
        'X-Host': 'mall.film-ticket.film.list'
      }
    }).then(res=>{
      this.setState({list:res.data.data.films})
    })
  }
  render() {
    return (
      <div>
        {
          this.state.list.map((item:IItem) => {
            return <li key={item.filmId} onClick={()=>{
              this.props.history.push('/detail/'+item.filmId)
            }}>{item.name}</li>
          })
        }
      </div>
    )
  }
}

防止this.props.match.params.id报错

  • 方法一:
    RouteComponentProps对this.props.match做规范
    IParam对this.props.match中的属性id做规范
  • 方法二:
    使用as断言(this.props.match.params as any).id
import React, { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom'

interface IParam {
  id:string
}
export default class Detail extends Component<RouteComponentProps<IParam>> {
  render() {
    return (
      <div>
        {/* 直接写id,会报错id属性不存在
          解决方法一:用as any
          解决方法二:IParam */}
        {/* Detail-{(this.props.match.params as any).id} */}
        Detail-{this.props.match.params.id}
      </div>
    )
  }
}

5. redux

对prevState和action做规范

import {createStore} from 'redux'

interface iState {
  show:boolean
}
interface iAction {
  type:string,
  payload?:any
}
const reducer = (prevState:iState={
  show:true
},action:iAction)=>{
  let newState = {...prevState};
  switch(action.type){
    case 'show':
      newState.show = true;
      return newState;
    case 'hide':
      newState.show = false;
      return newState;
    default :
      return prevState;
  }
}

const store = createStore(reducer);

export default store;

6. antdmobile+ts

import React, { Component,createRef } from 'react'
import { Button, Swiper } from 'antd-mobile'
import { SwiperRef } from 'antd-mobile/es/components/swiper'

export default class App extends Component {
  myref = createRef<SwiperRef>();
  colors = ['#ace0ff', '#bcffbd', '#e4fabd', '#ffcfac'];
  items = this.colors.map((color, index) => (
    <Swiper.Item key={index}>
      <div style={{height:'200px',width:'100%',background: color}}>
        {index + 1}
      </div>
    </Swiper.Item>
  ));

  render() {
    return (
      <div>
        <Swiper ref={this.myref}>{this.items}</Swiper>
        <Button color="danger" onClick={()=>{
          this.myref.current?.swipePrev();//原生js方法?前为真就执行?后的代码
        }}>上一个</Button>
        <Button color="primary" onClick={()=>{
          // (this.myref.current as any).swipeNext();
          (this.myref.current as SwiperRef).swipeNext();
        }}>下一个</Button>
      </div>
    )
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值