约束泛型类型T和K其中K扩展keyof T和T [K]是布尔值?

时间:2017-07-09 10:41:16

标签: typescript

我无法在某处使用any来检查以下功能类型。

export function makeToggleState<T, K extends keyof T>(obj: {new(): T}, prop: K) {
  return (state: T, show: boolean|null = null) => {
    if (show === null) {
      state[prop] = !state[prop]
    } else {
      state[prop] = show
    }
  }
}

class State {
    value = true
}

makeToggleState(State, 'value')

我收到此错误:

Type 'false' is not assignable to type 'T[K]'.
  Type 'false' is not assignable to type 'T[string]'.
(parameter) prop: K extends keyof T

告诉编译器我想要K extends keyof TT[K] is boolean的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

makeToggleState声明中无法使用此约束,但您可以使用T和mapped type T & {[n in K]: boolean}的交集来为其返回的函数声明它的状态参数。

export function makeToggleState<T, K extends keyof T>(obj: {new(): T}, prop: K) {
    return (state: T & {[n in K]: boolean}, show: boolean|null = null) => {
    if (show === null) {
      state[prop] = !state[prop]
    } else {
      state[prop] = show
    }
  }
}

class State {
    value = true;
    name = 'q';
}

const toggleValue = makeToggleState(State, 'value');

const s = new State();
toggleValue(s)


const toggleName = makeToggleState(State, 'name'); // ok

// but does not compile when you try to use it
toggleName(s);

//Argument of type 'State' is not assignable to parameter of type 'State & { name: boolean; }'.
//  Type 'State' is not assignable to type '{ name: boolean; }'.
//    Types of property 'name' are incompatible.
//      Type 'string' is not assignable to type 'boolean'.