如何检查某些内容是否可以是 TypeScript 中的字符串?

问题描述 投票:0回答:2

我想创建一个 TypeScript 类型来检查元素是否可以是字符串。

这意味着该元素可以具有“string”或“any”类型,但不能具有“number”、“boolean”、“number[]”、“Person”等类型。

我尝试使用条件类型,但我找不到如何排除“所有不可能是字符串的”。

我也尝试了排除类型,但这并不是我想要的。

编辑

我更好地解释了我的问题:我创建了一个静态方法

foo(data)
,如果数据是
string
,它将执行某些操作并返回
string
,或者执行其他操作,如果数据不是
number
,则返回
string
.

为此,很简单,我可以像这样进行重载:

class FooClass {

    static foo(data: string): string
    static foo(data: any): number
    static foo(data: any): string | number {
        if (typeof data === 'string') {
            return 'a';
        } else {
            return 2;
        }
    }
}

现在,假设如果

foo()
不是
data
,则
string
方法将抛出错误。我有两个案例:

  • 如果该方法的用户不知道数据的类型(可能是

    string
    ),我希望他可以使用此方法,如果不是
    string
    ,我将返回错误。

  • 如果用户知道数据的类型(例如,

    number
    ),我想告诉他这是不可能的,它不可能是
    string
    。我想告诉大家的是,这是在类型检查时进行的(IDE 中显示的错误),而不是在运行时进行。

class FooClass {

    static foo(data: string): string
    static foo(data: NotAString): Error
    static foo(data: any): string | Error {
        if (typeof data === 'string') {
            return 'a';
        } else {
            return new Error();
        }
    }
}
let foo1: string;
const bar1: string = FooClass.foo(foo1);  // No error
let foo2: any;
const bar2: string = FooClass.foo(foo2);  // No error
let foo3: number;
const bar3: string = FooClass.foo(foo3);  // Error (displayed on the IDE)
let foo4: Bar;
const bar4: string = FooClass.foo(foo4);  // Error (displayed on the IDE)

我想知道如何定义类型 NotAString(或其相反的 CouldBeAString)。

有什么想法吗?

谢谢!

typescript types conditional-statements
2个回答
6
投票

您似乎将类型系统与功能检查混淆了。

如果您需要在运行时检查某些内容是否是字符串,您将使用与普通 JS 中相同的逻辑。

运行时检查属性

if (typeof something === 'string') { ... }

如果我们谈论的是从 API 或类似的东西获取的数据,你总是需要使用这样的东西,因为类型系统不会为你进行自动运行时检查。

条件型疏化

如果您需要创建一个条件类型来允许您对参数进行类型细化,有几种方法可以实现。不过,这里需要注意的一件事是:

  • unknown
    是当前版本TS中的默认类型,而不是
    any
  • unknown
    any
    表示该语言中的任何有效数据类型。你不能说某件事是
    unknown
    但不能说
    number
    boolean
  • 如果你不知道什么是用的
    unknown
  • 如果你知道它是一个对象,但不确定它有什么属性,你可以将它定义为
    Record<string, unknown>

对于类型细化,您可以使用泛型属性和 extends 关键字的组合。

type Result<T> = T extends string
  ? A
  : T extends boolean
  ? B
  : T extends number
  ? C
  : never;

其中A、B、C是基于泛型类型的结果类型。

如果没有显式设置泛型参数,则传入的 prop 默认为

unknown
类型。您还可以将其范围限制为输入参数可以包含的几个值,以进行更精细的控制。


0
投票

NotAString
很简单:

type NotAString = number | boolean | symbol | bigint | null | undefined | object

另一方面,定义

CouldBeAString
的唯一方法是使用类型参数:

type CouldBeAString<S, R = S> = string extends S ? R : S extends string ? R : never

现在你可以做:

function foo<S>(data: CouldBeAString<S>) { ... }

foo(1) // Error!
foo(1 as string | number) // works
foo(1 as unknown) // works
foo(1 as '1' | 1) // works
foo('1') // works
© www.soinside.com 2019 - 2024. All rights reserved.