简体   繁体   English

对象不工作的 JsDoc 联合类型

[英]JsDoc union type with objects not working

I'm at my wits end with this.我对此束手无策。 It seems like it should work, I've been wrestling with it for hours, but I'm not sure what's wrong.似乎它应该可以工作,我已经为此苦苦挣扎了几个小时,但我不确定出了什么问题。 This is the smallest example I could come up with.这是我能想到的最小的例子。 I even have a type guard.我什至有一个类型后卫。

/** @typedef {{ a: string }} TypeA*/
/** @typedef {{ b: string }} TypeB*/
/** @typedef {(TypeA | TypeB) } TypeC */

/** @type {TypeC} */
let typeC;

console.log(typeC.b) // autocompletion for property b doesn't work

I get the error:我得到错误:

Property 'b' does not exist on type '{ a: string; } | { b: string; }'.
  Property 'b' does not exist on type '{ a: string; }'.ts(2339)

I found that a jsdoc style type guard lets me access the properties of TypeC if I am able to duck type it as TypeB.我发现一个 jsdoc 风格的类型保护可以让我访问 TypeC 的属性,如果我能够将其键入为 TypeB。

/** @typedef {{ a: string }} TypeA*/
/** @typedef {{ b: string }} TypeB*/
/** @typedef {(TypeA | TypeB) } TypeC */

/**
 * @param {*} value
 * @returns {value is TypeB}
 */
function typeIsB(value) {
  return true;
}

/** @type {TypeC} */
let typeC;

if (typeIsB(typeC)) {
  console.log(typeC.b) // no error, autocomplete works when typing typeC.b
}

Screenshot of autocomplete working:自动完成工作的屏幕截图:

在此处输入图像描述

I think you are looking for the intersection of A and B, not the union.我认为您正在寻找 A 和 B 的交集,而不是联合。 Here is the typescript code for your issue fixed:这是修复问题的 typescript 代码:

interface A {
  a: string;
}

interface B {
  b: string;
}

type C = A & B;

When you say that a value is of type A or B, the typescript compiler does not know which type of value is refrenced by that variable.当您说一个值是 A 或 B 类型时,typescript 编译器不知道该变量引用了哪种类型的值。

/** @typedef {{ a: string }} TypeA*/
/** @typedef {{ b: string }} TypeB*/
/** @typedef {(TypeA | TypeB) } TypeC */

/** @type {TypeC} */
let typeC;

console.log(typeC.b) // autocompletion for property b doesn't work

You need a condition to determine the actual type of the value referenced by typeC.您需要一个条件来确定 typeC 引用的值的实际类型。 For example:例如:

if ('a' in typeC) {
    console.log(typeC.a) // autocompletion for property a works       
} else {
    console.log(typeC.b) // autocompletion for property b works       
}

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

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