简体   繁体   English

Typescript 不能正确推断类型

[英]Typescript not correctly inferring type

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;

In the above example, why is the assignment for e giving error?在上面的例子中,为什么e的赋值会出错? Why is TS not inferring that is_prop will be true为什么 TS 不推断is_prop将是真的

Typescript playground Typescript 操场

The error is because a is of type A :错误是因为a属于A类型:

const a: A = new A(true);

In the ternary, you check that is_prop is true , but the variable a is still of type A .在三元中,您检查is_prop是否为true ,但变量a仍然是A类型。 The property has been narrowed to true , but a hasn't changed types.属性已缩小为true ,但a没有更改类型。 As an example, this code would be valid based on your narrowing:例如,根据您的缩小范围,此代码将是有效的:

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

If you want to be able to narrow the type of a , you need to say that it can be one of several types by stating that it's a union:如果您希望能够缩小a的类型,您需要通过声明它是联合来说明它可以是多种类型之一:

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

playground with some more alternatives.有更多选择的游乐场

You get that error because of this line of code由于这行代码,您会收到该错误

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

boolean is not a subset of true, so you can't assign class A to type A1: boolean 不是 true 的子集,因此您不能将 class A 分配给类型 A1:

you could try this:你可以试试这个:

type A1 = A & {is_prop: boolean};

or this:或这个:

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

That's because that true doesn't equal boolean type那是因为true不等于boolean类型

And I don't think you need to declare type of the variables ab c again而且我认为您不需要再次声明变量ab c的类型

They can be directly implicitly declared through the following generics .它们可以通过以下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;

In this way, you don't have to declare type A1 A2 C and declare type A1 | null这样就不用声明类型A1 A2 C和声明类型A1 | null A1 | null to e , and then you can get more simplified code like that A1 | nulle ,然后你可以得到更简化的代码

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;

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

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