打字稿没有正确推断类型

时间:2021-04-13 04:15:46

标签: typescript typescript-typings

class A {
    readonly is_prop: boolean;
    constructor(is_prop: boolean) {
        this.is_prop = is_prop;
    }
}

class B {
    readonly my_prop: boolean;
    constructor(my_prop: boolean) {
        this.my_prop = my_prop;
    }
}

type A1 = A & {is_prop: true};
type A2 = A & {is_prop: false};

type C = A1 | A2 | B;

const a: A = new A(true);
const b: A = new A(false);
const c: B = new B(true);

const e: A1 | null = a.is_prop ? a : null;

在上面的例子中,为什么 e 的赋值会出错?为什么 TS 不推断 is_prop 将是真的

Typescript playground

3 个答案:

答案 0 :(得分:1)

错误是因为 aA 类型:

const a: A = new A(true);

在三元组中,您检查 is_prop 是否为 true,但变量 a 仍为 A 类型。 属性 已缩小为 true,但 a 未更改类型。例如,根据您的缩小范围,此代码将有效:

const trueVal: true | null = a.is_prop ? a.is_prop : null 

如果您希望能够缩小 a 的类型,您需要通过声明它是联合来说明它可以是几种类型之一:

const a: A1|A2 = new A(true);

playground 有更多选择。

答案 1 :(得分:0)

你因为这行代码而得到那个错误

type A1 = A & {is_prop: true}; //for class a, is_prop is boolean

boolean 不是 true 的子集,因此您不能将 A 类分配给类型 A1:

你可以试试这个:

type A1 = A & {is_prop: boolean};

或者这个:

const e: A1 | null = a.is_prop ? a as A1: null;

答案 2 :(得分:0)

那是因为 true 不等于 boolean 类型

而且我认为您不需要再次声明变量 a b c 的类型

它们可以通过以下 generics 直接隐式声明。

class A<T = boolean> {
  readonly is_prop: T extends boolean ? T : never;
  constructor(is_prop: T extends boolean ? T : never) {
    this.is_prop = is_prop;
  }
}

class B {
  readonly my_prop: boolean;
  constructor(my_prop: boolean) {
    this.my_prop = my_prop;
  }
}

type A1 = A & { is_prop: true };
type A2 = A & { is_prop: false };

type C = A1 | A2 | B;

const a = new A(true);
const b = new A(false);
const c = new B(true);

const e: A1 | null = a.is_prop ? a : null;

这样就不用声明type A1 A2 C,将type A1 | null声明为e,这样就可以得到更简化的代码了

class A<T = boolean> {
  readonly is_prop: T extends boolean ? T : never;
  constructor(is_prop: T extends boolean ? T : never) {
    this.is_prop = is_prop;
  }
}

class B {
  readonly my_prop: boolean;
  constructor(my_prop: boolean) {
    this.my_prop = my_prop;
  }
}

const a = new A(true);
const b = new A(false);
const c = new B(true);

const e = a.is_prop ? a : null;