/** 为函数定义类型 */ // 为函数的参数指定类型,为函数的返回值指定类型 function add(x: number, y: number): number { return x + y; } let myAdd = function (x: number, y: number): number { return x + y; } // 完整的函数 let myAdd2: (x: number, y: number) => number = function (x: number, y: number): number{ return x + y } let myadd3: (x: number, y: number) => number = function (x: number, y: number) { return x + y } let myadd4: (b: number, y: number) => number = function (x: number, y: number) { return x + y; } let myadd5: (x:number, y: number) => number=function(x,y){return x+y} // 可选参数和默认参数:ts里传入一个函数的参数个数必须与函数期望的参数个数一致 function buildName(firstName: string, lastName: string) { return firstName + " " + lastName } let result = buildName("jsck", "bruce") let result1 = buildName("jsck") console.log(result1) // 可选参数必须放在后面 function buildName2(firstName: string, lastName?: string) { return firstName + " " + lastName } let result2 = buildName2("jsck", "bruce") let result3 = buildName2("jsck") console.log(result2) console.log(result3) // 默认参数,当用户没有传值或者传递的值是undefined的时候生效 function buildName3(firstName: string, lastName="smith") { return firstName + " " + lastName } let result4= buildName3("bob", undefined) // 剩余参数 function buildName4(firstName: string, ...restOfName: string[]) { return firstName + ',' + restOfName.join(",") } let employeeName = buildName4("xiaoju", "weimeng", "ruixin", "tengying") console.log(employeeName) /** 泛型 */ // 使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 function identity(arg: number): number { return arg; }; // 类型变量 function identity1<T>(arg: T): T { return arg; } let output = identity1<string>("myString") let output2 = identity1("myString") // 类型断言,根据参数判断T的类型 function loggingIdentity<T>(arg: T[]): T[] { console.log(arg.length) return arg; } function loggingIdentity2<T>(arg: Array<T>): Arrary<T> { console.log(arg.length) return arg; } /** symbol */ let sym = Symbol(); let obj = { [sym]: "value" }; console.log(obj[sym]); // "value" // symbol表示独一无二的的,他接受一个字符串作为参数,表示对symbol的描述,如果参数是一个对象,它会调用对象的toString的方法转为string const log = {} log.levels = { DEBUG: Symbol('debug'), INFO: Symbol('info') } console.log(log.levels.DEBUG) // 作为属性名的写法 let mySymbol = Symbol(); let a = {}; a[mySymbol] = 'Hello!'; let a1 = { [mySymbol]: 'Hello!' } let a2 = {} Object.defineProperty(a, mySymbol, { value: 'Hello!' }); // 属性名的遍历 // Object.getOwnPropertySymbols方法返回一个数组,成员是当前对象的所有用作属性名的Symbol值 const objSymbol = {} let aa = Symbol('aa'); let bb = Symbol('bb'); objSymbol[aa] = 'aaa'; objSymbol[bb] = 'bbb'; const objectSymbols = Object.getOwnPropertySymbols(objSymbol) console.log(objectSymbols) //重新使用同一个Symbol值,Symbol.for(),Symbol.keyFor() //Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值 console.log(Symbol.keyFor(mySymbol)) /** 枚举 */ // 使用枚举我们可以定义一些带名字的常量,使用枚举可以清晰的表达意图活创建一组有区别的用例。 // 数字枚举 enum Direction { Up = 1, Down, Left, Right } enum Response { No = 0, Yes =1 } function respond(recipient: string, message: Response): void { // ... } respond("text", Response.No) // 字符串枚举,每一个字符串枚举里,每个成员必须用字符串字面量,或另外一个字符串枚举成员进行初始化 enum Direction2 { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } enum E1 { X,Y,Z } console.log(E1.X, E1.Y) enum E2 { A=1, B, C } console.log(E2.B) enum FileAccess { // constant members None, Read = 1 << 1, Write = 1 << 2, ReadWrite = Read | Write, // computed member G = "123".length } console.log(FileAccess.Read, FileAccess.Write, FileAccess.ReadWrite, FileAccess.G) // 联合枚举与枚举成员类型