Typescript 基本语法+ 新特性

TypeScript :

1、获取TypeScript

$ npm install -g typescript
1.1 编译TypeScript
$ tsc helloworld.ts
# helloworld.ts => helloworld.js

2、TypeScript基础语法

2.1 Boolean 类型
let isDone: boolean  = false;
2.2 Number 类型
let count: number = 10;
2.3 String 类型
let name:   string = "zx"
2.4 Array 类型
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];(泛型语法)
2.5 unknown 类型
类型只能被赋值 any 类型 和 unknown 类型
2.6 Tuple 类型(元组)
let tupleType: [string, boolean];
tupleType = ["Semlinker", true];
2.7 Any 类型
let notSure: any = 666;
notSure = "Semlinker";
notSure = false;
在 TypeScript 中,任何类型都可以被归为 any 类型。这让 any 类型成为了类型系统的顶级类型(也被称作全局超级类型)。
2.8 Enum 类型
数字枚举:
enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST,
}
默认情况下,NORTH 的初始值为 0,其余的成员会从 1 开始自动增长

字符串枚举:
enum Direction {
  NORTH = "NORTH",
  SOUTH = "SOUTH",
  EAST = "EAST",
  WEST = "WEST",
}       
      
异构枚举:
enum Enum {
  A,
  B,
  C = "C",
  D = "D",
  E = 8,
  F,
}
   
2.9 Void 类型
某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。当一个函数没有返回值时,你通常会见到其返回值类型是 void:

tips: 需要注意的是,声明一个 void 类型的变量没有什么作用,因为它的值只能为 undefined 或 null:
2.10 Never 类型
never 类型表示的是那些永不存在的值的类型。 
例如,never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。

在 TypeScript 中,可以利用 never 类型的特性来实现全面性检查,具体示例如下:
            type Foo = string | number;
      function controlFlowAnalysisWithNever(foo: Foo) {
          if (typeof foo === "string") {
            // 这里 foo 被收窄为 string 类型
          } else if (typeof foo === "number") {
            // 这里 foo 被收窄为 number 类型
          } else {
            // foo 在这里是 never
            const check: never = foo;
          }
      } 
2.11 TypeScript 断言
2.11.1尖括号 形式
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
2.11.2 as语法
let someValue: any  = "this is string"
let strLength: number = (someValue as string).length
2.12 类型守卫(类型保护)
2.12.1 in 关键字
interface Admin {
    name:   string;
    privileges: string[];
}

interface Employee {
     name: string;
     startDate: Date;
}

type UnknownEmployee = Employee | Admin

function printEmployeeInformation( emp: UnknownEmployee) {
    console.log( "Name:" + emp.name)
    if("privileges" in emp) {
        console.log("Privileges" + emp.privileges);
    }
    if("startDate" in emp) {
        console.log("Start Date" + epm.startDate)
    } 
}
2.12.2typeof 关键字
function padLeft( value: string, padding: string | number) {
    if(typeof padding === "number"){
        return Array(padding + 1).join("") +value;
    }
    if(typeof padding === "string") {
        return padding + value
    }
    throw new Error(`Expected string or number, got '${padding}'.`)
}

注释:typeof类型保护只支出两种形式;typeof v === "typename" 和 
typeof v !=="typename", typename 必须是 "string","number","boolean"或 "symbol"; 但是 typeof  不会阻止你与其他字符串比较; 语言不会把那些表达式当成类型保护
2.12.3 instanceof关键字
interface Padder {
    getPadderString() : string;
}
class SpaceRepeatingPadder implements Padder {
     constructor(private numSpaces: number ) {}
     getPadderString() {
            return Array(this.numSpace + 1 ).join("");
     }
}

class StringPadder implements Padder {
        constructor(private value:string ) {}
        getPaddingString(){
            return this value;
        }
}

let padder : Padder = new SpaceRepeatingPadder(6);
if(padder instanceof SpaceRepeatingPadder) {
    // padder的类型收窄为:"SpaceRepeatingPadder"
}
2.12.4 自定义类型保护的类型谓词
function isNumber (x :any): x is number {
    return trpeof x === "number"
}
function isString( x :any ): x is string {
    return typeof x === "string"
}

3.vue3.0 新特性语法

3.1 setup函数
一、生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数; 在setup 函数中是无法访问到 data 以及 medthods 的数据以及方法
二、setup函数是 Composition API(组合API)的入口
三、在setup方法中。由于还没有执行 Created周期 无法访问到this
四、setup函数只能是同步的不能是异步的
五、setup 函数定义的方法以及变量最后必须 return 出去 不然模板中是无法使用的
export default {
  setup(props, context) {
    context.attrs, 
    context.slots,
    context.parent, 
    context.root, 
    context.emit
  }
};
3.2 Reactive、Ref、toRef、IsRef

reactive 和 ref 均为 数据响应式监听 方式
ref 函数传入一个值作为参数,返回一个基于该值的响应式ref对象 该对象一旦被访问或改变,如下 修改 count.value 的值 就可以触发重新渲染显示最新的值;但是ref虽然写法简单,但是只能监听一些简单的数字、字符串、布尔之类的简单类型;

 eg:
 export default {
    setup () {
      const count = ref(0)
      const state = reactive({
        reactiveField: 0,
        a: [
          {
            a:1
          }
        ]
      })
      const addRef = () => {
        count.value++
      }
      const addReactive = () =>{
        state.reactiveField++
      }
      const addA = () => {
        state.a[0].a++
      }
      return {
        count,
        ...toRefs(state),
        addA,
        addRef,
        addReactive
      }
    }
  } 

一、toRef 将响应式对象变为普通的对象 ...toRef(data) 在模板中即可使用数据 无需增加 例: data.value
二、reactive 响应式数据 readonly 和 reactive 是互斥的数据结构

3.3 defineComponent

defineComponent函数,只是对setup函数进行封装,返回options的对象;
defineComponent最重要的是:在TypeScript下,给予了组件 正确的参数类型推断 。

export function defineComponent(options: unknown) {
    return isFunction(options) ? { setup: options } : options
}
3.4 watchEffect 监听

接收一个函数,当依赖改变时,重新调用该函数

const count  = ref(0)
watchEffect(()=> console.log(count.value))
setTimeout(()=>{
    count.value ++
},1000)

watchEffect()在setup()或生命周期钩子中被调用时,监听就始终存在该组件的生命周期中,直到组件unmount.另一种卸载监听的情况是,watchEffect()返回一个stop handler,调用该handler即可停止监听。

const stop = watchEffect(()=>{
      //todo
})
stop()

当向后台获取数据时,watchEffect 接受async回调函数

const data = ref(null)
watchEffect( async ()=> {
        data.value = await fetchData(props.id)
})

在 update 函数也有 watch Effect 用户定义的watchEffect 会在组件中update 之后再去调用

<template>
  <div>{{ count }}</div>
</template>

<script>
  export default {
    setup() {
      const count = ref(0)

      watchEffect(() => {
        console.log(count.value)
      })

      return {
        count
      }
    }
  }
</script>

上述代码,第一轮会同步打印count.value(在onmount生命周期前); 当count发生改变时,先执行组件更新,然后再去log

如果希望 watchEffect 中的回调函数 第一次执行,放在onmount 后

onMounted(()=>{
        watchEffect(()=>{
                //to do something
        })
})

如果想让 watchEffect() 调用发生在组件update前,或re-run同步,需要传递一个带有flush属性 ( 默认值为post ) 的option对象。

watchEffect(()=>{
    //....
},{
    flush: 'sync'
})
3.5 watch

watch:watch( source, cb, [options] )
参数说明:

  • source:可以是表达式或函数,用于指定监听的依赖对象
  • cb:依赖对象变化后执行的回调函数
  • options:可参数,可以配置的属性有 immediate(立即触发回调函数)、deep(深度监听

当监听 ref 类型时


<script>
import {ref, watch} from 'vue'
export default {
    setup() { 
        const state = ref(0)

        watch(state, (newValue, oldValue) => {
          console.log(`原值为${oldValue}`)
          console.log(`新值为${newValue}`)
          /* 1秒后打印结果:
                  原值为0
                  新值为1
          */
        })

        // 1秒后将state值+1
        setTimeout(() => {
          state.value ++
        }, 1000)
    }
}
</script>

当监听 reactive 类型时

<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({count: 0})

        watch(() => state.count, (newValue, oldValue) => {
          console.log(`原值为${oldValue}`)
          console.log(`新值为${newValue}`)
          /* 1秒后打印结果:
                  原值为0
                  新值为1
          */
        })

        // 1秒后将state.count的值+1
        setTimeout(() => {
          state.count ++
        }, 1000)
    }
}
</script>

同事监听多个值(数组形式展示)

<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'zs' })

         watch(
            [() => state.count, () => state.name], 
            ([newCount, newName], [oldvCount, oldvName]) => {
              console.log(oldvCount) // 旧的 count 值
              console.log(newCount) // 新的 count 值
              console.log(oldName) // 旧的 name 值
              console.log(newvName) // 新的 name 值
            }
          )

          setTimeout(() => {
            state.count ++
            state.name = 'ls'
          }, 1000)
    }
}
</script>
3.6 onRenderTracked onRenderTriggered 新钩子

除了2.x生命周期等效项之外,3.0Composition API还提供了以下调试挂钩

  • onRenderTracked
  • onRenderTriggered
    两个钩子都收到DebuggerEvent类似于onTrackonTrigger观察者的选项
export default {
  onRenderTriggered(e) {
    debugger
    // inspect which dependency is causing the component to re-render
  }
}

先更新到这里! 持续更新~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容

  • Vue3官网文档[https://vue3js.cn/docs/zh/guide/introduction.htm...
    一苏沨来阅读 3,175评论 0 7
  • # Vue3的改进及特点 1.性能的提升:打包大小减少 41%,初次渲染快 55%,更新快 133%,内存使用减少...
    华尔街的主导曲阅读 19,724评论 1 3
  • Vue 的下一代版本(3.0)终于在9.18日发布正式版了,代号居然叫“One Piece”,不知海贼王粉们会作何...
    飞空之羽阅读 643评论 0 0
  • 1.setup() setup() 函数是我们使用vue3的Composition API新特性提供了统一的入口。...
    遇一顽石阅读 1,343评论 0 2
  • 性能提升 打包大小减少41% 初次渲染快55%,更新快133% 内存使用减少54% 原因:重写虚拟dom的优化和t...
    violet_syls阅读 3,576评论 0 6