【问题标题】:Typescript enforce alias type in argument打字稿在参数中强制使用别名类型
【发布时间】:2020-06-05 18:43:31
【问题描述】:

我目前遇到类型联合/别名的问题。 我有一个可能为 null 或未定义的值的别名以及一个处理这些值的函数。

这很好,一切都很安全。在某些情况下,通过疏忽或其他任何事情,一个不能为 null 或 undefined 的安全值被传递给函数。这不会破坏任何东西,因为该函数也需要安全值,但 Typescript 不会抱怨。

代码如下所示:

type Maybe<T> = T | null | undefined;

function handleDangerousValue<T>(val: Maybe<T>): T {
    // Check stuff
    return val as unknown as T;
}

const safeValue: number = 1;
const unsafeValue: Maybe<number> = null;

// Would like a type error here
handleDangerousValue(safeValue);

// This is fine
handleDangerousValue(unsafeValue);

我想以某种方式让 Typescript 告诉我 safeValue 没有正确的类型。

我知道这不起作用,因为联合类型是如何定义的,但我不知道如何执行此操作的任何解决方案。 这可能可以通过让DangerousValue&lt;T&gt; 成为一个类来解决,但我更喜欢它作为一个类型,因为我不希望额外的样板来解决打字问题。

编辑:

我又修改了一些,取得了一些进展:

type Maybe<T> = T | null | undefined;
type EnforceMaybe<T> = Maybe<T> extends T ? Maybe<T> : never;

function handleDangerousValue<T>(val: EnforceMaybe<T>): T {
    // Check stuff
    return val as unknown as T;
}

const safeValue: number = 1;
const unsafeValue: Maybe<number> = null as Maybe<number>;

// Correctly finds issue
const n1: number = handleDangerousValue(safeValue);

// Now thinks that the return type should be a Maybe
const n2: number = handleDangerousValue(unsafeValue);

现在不能为空的值是不允许的,但是打字稿不能再推断Maybe的内部类型了。

我能以某种方式推断返回类型吗?

【问题讨论】:

  • 你不能让 TS 告诉你 safeValue 没有正确的类型,因为它有正确的类型。根据您的定义,DangerousValue&lt;T&gt; 也可以是 T。所以,number 类型的safeValue 完全可以从DangerousType&lt;number&gt; 分配。这个定义的类型并不意味着“可为空的T's”。是一个逻辑 OR...
  • 我知道,我认为我正确地传达了这一点。问题是如何更改 Typescript 的类型以告诉我用法不正确
  • 重点是,没有错误的用法……
  • 正如所指出的:I 的正确用法是,只有 can 为 null 或 undefined 的值可以传递给函数,而不是永远不会为空或未定义的值
  • 哟,你的类型定义是一个非空值满足契约的联合。所以将非空值作为DangerousValue&lt;T&gt; 传递是完全可以的。 number 实际上是 DangerousValue&lt;number&gt; 推断。如果您只期望可以为空的值,那么您应该更改别名...

标签: typescript


【解决方案1】:

通过转换返回类型来解决它:

type Maybe<T> = T | null | undefined;
type EnforceMaybe<T> = Maybe<T> extends T ? Maybe<T> : never;

function handleDangerousValue<R extends NonNullable<T>, T>(val: EnforceMaybe<T>): R {
    // Check stuff
    return val as unknown as R;
}

const safeValue: number = 1;
const unsafeValue: Maybe<number> = null as Maybe<number>;

// Correctly finds issue
const n1: number = handleDangerousValue(safeValue);

// Now thinks that the return type should be a Maybe
const n2: number = handleDangerousValue(unsafeValue);

知道返回时该值不会为null,因此应该可以强制转换它。对于强制转换,我创建了第二个泛型,它从 Maybe 类型中获取原始类型。

现在我不能将不可为空的值传递给函数,但如果传递了一个值,我会得到正确的返回类型。

Playground Link

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-16
    • 2020-10-20
    • 2019-11-02
    • 2023-02-06
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 2021-06-24
    相关资源
    最近更新 更多