如何在打字稿中使类型可选

How can make type optional in typescript

如何在 Typescript 中使某些类型可选?

我有以下代码:

const A = <T>(value: T) => new Clazz(value);
const B = <U>(value: U) => new Clazz(undefined, value);

class Clazz<T, U> {
  constructor(private a?: T, private b?: U) {}

  public map<Z>(callback: (value: T) => Z): Clazz<Z, U> {
    return this.a 
      ? A(callback(this.a)) 
      : B(this.b);
  } 
}

但是此代码失败并出现错误:

Type 'Clazz<Z, {}> | Clazz<undefined, U | undefined>' is not assignable to type 'Clazz<Z, U>'. 
Type 'Clazz<Z, {}>' is not assignable to type 'Clazz<Z, U>'. 
Type '{}' is not assignable to type 'U'.

解决这个问题的最佳方法是什么?

我的 tsconfig.json 看起来像这样:

{
  "compilerOptions": {
    "baseUrl": "",
    "declaration": true,
    "lib": ["es6", "dom"],
    "mapRoot": "./src",
    "module": "es2015",
    "moduleResolution": "node",
    "noEmitHelpers": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "outDir": "./dist",
    "sourceMap": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es2015",
    "typeRoots": [
      "./node_modules/@types"
    ]
  }
}

问题是map函数的return类型与方法A的return类型不匹配,因为A没有提供Clazz class 的预期构造函数参数。您可以使用与方法 B 相同的 work-around,即为 Clazz 构造函数的第二个参数传递 undefinednull 值如此:

const A = <T>(value: T) => new Clazz(value, null);
const B = <U>(value: U) => new Clazz(null, value);

class Clazz<T, U> {
  constructor(private a?: T, private b?: U|null) {}

  public map<Z>(callback: (value: T|undefined) => Z): Clazz<Z|null, U> {
    return this.a 
      ? A(callback(this.a)) 
      : B(this.b);
  } 
}

我必须承认我很难理解你在那里做什么以及为什么 - 最好有一个解释。

解决您的问题的一种方法是像这样参数化您的代码

const A = <T>(value: T) => new Clazz(value, null);
const B = <U>(value: U) => new Clazz(null, value);

class Clazz<T, U> {
  constructor(private a?: T, private b?: U|null) {}

  public map<Z>(callback: (value: T|undefined) => Z): Clazz<Z|null, U> {
    return this.a 
      ? A(callback(this.a)) 
      : B(this.b);
  } 
}

这可以编译,但我什至很难表达这张地图的作用