小白入门TS(三)---函数Function & 联合类型 & Class

497 阅读2分钟

Function

js中函数有两种定义方式

  1. Named Function
  2. Anonymous Function
function Func1(){
	console.log(1)
}

const func = function Func2(){
	console.log(123)
}

ts中如何定义函数

function Func1(name: string): string{
	return name
}

let func: (name: string) => string = function(nameFrom: string): string {
	return nameFrom
}

可选形参

使用 ?

function buildName(firstName: string,lastName?: string){
	if (lastName) return firstName + " " + lastName;
	else return firstName;
}

默认形参

如果默认形参 传入为 undefined 则,函数内使用其默认形参

function buildName(firstName: string,lastName='Sun'){
	return firstName + " " + lastName;
}
buildName('xy',undefined) // xy Sun

剩余形参

function buildName(firstName: string,...restOfNames: string[]){
	return firstName + restOfNames.join('')
}

关于this的使用

思考一个问题,createCardPicker中的箭头函数 换成普通函数 function(){} 会如何?

interface Card {
	suit: string
    card: number
}

interface Deck{
	suits: string[],
    cards: number[],
    createCardPicker(this: Deck): Card
}

let deck: Deck = {
	suits:['hearts','spades','clubs','diamonds'],
    cards: Array(52),
    createCardPicker: function(this: Deck){
    	return ()=>{
        	let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13)
            return {suit: this.suits[pickedSuit],card: pickedCard % 13}
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

函数重载

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string;card: number}[]): number
functino pickCard(x: number): {suit: sring,card: number};
function pickCard(x: any): any{
	if(typeof x == 'object'){
    	let pickedCard = Math.floor(Math.random() * x.length)
        return pickedCard
    }else if(typeof x == 'number'){
    	let pickedSuit = Math.floor(x/13)
        return {suit: suits[pickedSuit],card: x % 13}
    }
}

let myDeck = [
  { suit: "diamonds", card: 2 },
  { suit: "spades", card: 10 },
  { suit: "hearts", card: 4 },
];

let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

Unions 联合声明

非交叉型的联合声明

type NetwrokLoadingState = {
	state:"loading"
}

type NetworkFailedState = {
	state:"failed";
    code: number;
}

type NetwrokSuccessState = {
	state: "success";
    response: {
    	title: string;
        duration: number;
        summary: string;
    }
}

type NetworkState =
	NetwrokLoadingState 
	| NetworkFailedState 
	| NetwrokSuccessState;
// 防出错函数
function assetNever(x: never): never{
	throw new Error("Unexpected object:"+x)
}

function logger(state: NetworkState): string{
	switch(state.state){
    	case "loading":
        	return "loading";
        case "failed":
        	return `Error ${state.code} downloading`
        case "success":
        	return `Success ${state.title}.${state.duration}.${state.summary}`
    }
    	default:
	      return assertNever(state);
}

交叉型类型声明

interface Singer {
  age: number
  song: string
}

interface Dancer {
  age: number
  style: string
}

type Artist = Singer & Dancer

const artist: Artist = {
  age: 18,
  song: '借口',
  style: 'hip hop',
}

class 类

继承、私有、公用、受保护的修饰词

继承 本身es6也有,私有属性,在ts3.8中,也支持了 #prop 的定义方式;private、public、protected 为 ts 特有的属性

ts 3.8开始支持私有作用域

class Animal{
	#name: string;
    constructor(theName: string){
    	this.#name = theName;
    }
}

class Animal {
  #name: string;
  constructor(theName: string) {
    this.#name = theName;
  }
}

new Animal("Cat").#name; //读取会报错
//Property '#name' is not accessible outside class 'Animal' because it has a private identifier.

read-only 属性

class Person{
	readony private age;
}

参数属性

可快速注册属性

//无需写 this.name: string;
class Person {
  constructor(public name){}
}

const p = new Person("sxy")
console.log('p.name',p.name);

set get

set 可作为变量初始化时validate的一种方式

type SexType = 'unknown'|'male' | 'female'

class Person {
  #sex:SexType =  'unknown';
  constructor(public name){}
  set sex(sexStr: SexType){
    this.#sex = sexStr
  }
  get sex(){
    return this.#sex
  }
}

const p = new Person("sxy")
console.log('p.name',p.name);

上述代码报错时:Private identifiers are only available when targeting ECMAScript 2015 and higher

解决方案:

tsconfig.json

{
    "compilerOptions": {
        "target": "es6"
    }
}

static

静态类和方法,“类本身”及“子类”才可以使用