繁体   English   中英

从其属性推断 Object 通用(返回 function 类型)

[英]Infer Object Generic from its propery (return function type)

我想制作一个可以从 function data的返回值推断类型T的接口,以便 function step可以将this的类型作为参数接收。

像这样:

type DefInstance = {
    
    x : number,
    y : number,
};

type StateInstance<T> = {
    data : () => T,
    step : (this : DefInstance & T, turn : number) => boolean,
};

const instance : StateInstance<{
    f : number
}> = {
    data : () => ({
        f : 0,
    }),
    step : function(turn){
        this.f++;
        
        if(this.f > 3){
            this.x += 1;
            this.f = 0;
        }
        console.log(`move on turn ${turn}`);          
        return true;
    }
}

但不必指定类型。

/*
  stuff from above
*/

//so it looks like this
const instance : StateInstance = {
    data : () => ({
        f : 0,
    }), //here i define the function and the return value
    step : function(turn){
        this.f++; //here i access the members described in the return value of data
        
        if(this.f > 3){
            this.x += 1;
            this.f = 0;
        }
        console.log(`move on turn ${turn}`);          
        return true;
    }
}

类似于 Vue.js (v3) 中使用data function 所做的,其中所有方法都可以访问组件的 state 的成员

/*vue stuff*/
export default defineComponent({
  data : () => ({ count : 10 }),
  methods : {
    countUp() { this.count++; } //Autocompleted property `count` when access `this`
  }
})

我知道 Vue 使用 function(后面使用了很多 generics),但我想知道如何仅使用一种类型(或接口) (如果可能)来做到这一点。 或者,如果它只能使用函数,那么如何使用 function 来实现。

如果你需要重用 function vera 提到的那个magic ,你可以使类型构造函数通用:

import { apply } from 'free-types'

const of = <$T extends Type<1>>() => <T>(i: apply<$T, [T]>) => i;

const State = of<$StateInstance>();

const instance = State({
    data : () => ({
        f : 0,
    }), //here i define the function and the return value
    step : function(turn){
        this.f++; //here i access the members described in the return value of data
        
        if(this.f > 3){
            this.x += 1;
            this.f = 0;
        }
        console.log(`move on turn ${turn}`);          
        return true;
    }
})

$StateInstance可以这样定义

interface $StateInstance extends Type<1> {
   type: StateInstance<this[0]>
}

或者,如果您不需要StateInstance做任何其他事情:

interface $StateInstance extends Type<1> {
    type: { [K in 'data'|'step']: this[K] }
    data : () => this[0],
    step : (this : DefInstance & this[0], turn : number) => boolean,
};

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM