函数
typescript
复制代码
// 函数 对函数增加类型 函数的参数、返回值、重载 本身校验 等等
let sm2 = (x:string):string => {return x}
sm2的类型是 (x:string) => string
// 可选参数?: 这个默认带着|undefined 需要断言
// 默认值和可选参数不能一起使用 s?:number = 1
// 剩余参数 ...args:Array<number>
// 函数重载
function ak(val:number|string): number[] | string[] {
// 这个处理完的返回的是两种类型 number[] | string[] 这样显然不对 传入 number 应该是 number[] 后面的那个一样。
}
// 所以需要重载
// 根据参数不同实现不同根据不同的传入返回对应类型的参数的结果。
function ak(val:number):number[]
function ak(val:string):string[]
function ak(val:number|string): number[] | string[]{ // 实现
}
// 实现的类型需要宽泛
// 也可以这么写
function ak(val:any):any[] {
//
}
类
typescript
复制代码
// 类最早用的是构造函数构造的。 es6后才有类的概念。
// 不想初始化就把严格模式关掉。
// 或者直接用x!:number y!:number
class Test {
// 构造函数
public x:number; // 必须初始化 声明在这里或者在constructor 默认public
// 构造函数 public y:number 这么写就不需要在在外边声明了。直接就放在实例上无需再次声明。
constructor(x:number, public y:number){
this.x = x;
}
}
// ts 总的修饰符
// 默认 public 自己 子类 子孙之外的都可以用
// private 只有自己可以用 在构造函数上用 private修饰是不能被new的 单例用。也无法被继承。
// protected 自己和子孙 构造函数如果被 protected 修饰也是不能被new 的但是可以被继承。
// readonly 只读只能在声明时候使用并且必须赋初始化的值。 还可以在constructor里面声明,只要声明的地方就行。 readonly object可以修改内部属性但是不能改地址。
class Sa {
public readonly sl; // 可以放到构造函数里面在声明,初始化以后不能修改。
constructor(){
this.sl = 1;
}
}
class anylmo{
}
class pg extends anylmo {
constructor(){
super(); // 继承的时候如果用了 constructor 必须 执行super 这个相当于执行了 anylmo.call(this, xxx,xxx);
}
}
// static 不是ts里面的
class Test02 {
// es6 最后用的是defineproperty
static get cc(){
return 'aa'
}
// static cc = 1; js 支持es7的语法 这个是es7的语法
static say(){
// this 指向的是调用者 static是es6的语法
// super.父类的静态方法 就是父类
} // es6不支持es7支持
say(){ // 这样就是原型方法。
}
// 原型的属性怎么定义
get customDefineproperty(){ // 在原型上定义了属性
return 'aaa';
}
get setCustomDefineproperty(val=''){ // 在原型上定义了属性
return 'aaa';
}
say2(){
// 原型中的super指向的是父类的原型。
// 这里的super指向的是谁?
}
// 静态方法可以被继承
// 通过extendStatics 继承静态的属性。 让子通过链找到父类。
// 静态属性方法都可以继承 子访问父用super访问 super 在构造方法和静态方法都默认指向父类。
}
装饰器
typescript
复制代码
// 是一个实验性的语法
// 扩展类、扩展方法、装饰属性
// 为了扩展不同的方法 类 属性而统一的方法。
// experimentalDecorators tsconfig.json 这个属性加上才能用这些实验的属性。
// @target 当前的类被修饰的类
function Zsq_addSay(target:any){
}
@Zsq_addSay
// 装饰器是个可以多个从下往上执行。 有个一个数组存放了这些装饰器没一个都会执行。
// 内部用了 decorators 然后用 for 从最后一个开始i执行。 从后往前执行,先执行的作为参数给后一个。
class mq{
}
// 装饰器接收参数
function Zsq_addSay(arg:any){
return function(target:any){
// 给原型增加方法。
// 用装饰器加完了在 new mq2() 的时候 实例上是没有 addSay这个方法提示的
target.prototype.addSay = function(){
}
}
}
@Zsq_addSay(123) // 带括号的是正序 返回的装饰函数是反序。
class mq2{
// 可以声明一下
addSay!:()=>void
}
// 装饰器修饰属性
/**
* @target 原型
* @key 被装饰属性名字
*/
function Zsq_sx(target:any, key:any){
let val:string = ''; // definedproperty需要一个地三方值来介入
Object.defineProperty(target, key, { // 给原型 target 定义一个属性key
get(){
return val;
}
set(vals){
// 因为这个是后执行的 public s:string = 1; 所以执行这个时候的会走到这里来 执行这个就跑到原型来了。
val = vals;
}
})
}
class mq3 {
@Zsq_sx // 先执行装饰的逻辑
public s:string = 1; // 然后在执行的它 生成的代码s是放到了 this上了
}
// 属性装饰也可以修饰静态属性
// 修饰静态属性Object.defineProperty(target, key, {
get(){
// target 是类
// key属性名字
return target[key] // 这个是在类上
}
set(val){
target[key] = val;
}
})
// 属性 和 方法 装饰器 如果修饰的是实例 target是原型 静态是类
// 装饰描述方法
// target 原型
// key 方法名字
// descriptor 描述符
function Zsq_func(target:any, key:any, descriptor:PropertyDescriptor){
descriptor.writable = true;
}
class mq3{
@Zsq_func
drink(@arg args){
}
}
/ 修饰方法里面的参数
// target原型
// 参数名字
// 当前参数位于第几个。 在arguments 位于第几个
function arg(target:any, key:string, index:number) {
}
// 如果修饰同时存在
// 类、属性、方法、参数
接口
typescript
复制代码
// 可以被类继承和实现
// type可以使用联合类型,interface没有联合类型。
// 用接口描述对象
const getObj = (obj:{name:string}) {
// 可以这么描述类型
}
interface IC {
name:string
age:number
}
// 描述函数
interface Fn {
(x:number, b:number) : number
}
// 描述函数还带上属性
// 混合类型
interface ICount {
():number // 描述函数
count:number // 描述函数的属性
}
const s:ICount = (() => {
return s.count++
}) as ICount
s.count = 0;
// 接口描述对象结构的
interface xinfo{
a:string
b:string
}
const cxinfo:xinfo = {
a:'',
b:'',
c:'', //这个怎么兼容?
} as xinfo
// 解决方案1 直接 as xinfo 断言的时候接口限制的数据必须有。
// 解决方案2 接口合并
interface a{ // 接口同名会合并!
a:number
}
interface a{
b:number
}
a 就有了ab
// 接口继承 a extends b ab是接口
// 可选属性 ?:
// interface b{[balabalkey:string]:string}
// 可以索引类型[idx:number]:any // 数组
// 取到接口内部属性
interface A{
a:number
}
type xlc = A['a'] 取到a对应的类型
// 被实现
interface F{
readonly name:string
say():void
}
class Ak implements F {
say():string{ // 上面如果是void代表不关心返回值是啥都行,如果上面写死了就需要和上面约定一样。
}
}
// 接口中的方法都是抽象的
// 抽象类 - 这东西不能被new
abstract class M {
abstract say():void
}