Function
js中函数有两种定义方式
- Named Function
- 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
静态类和方法,“类本身”及“子类”才可以使用