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

Gil*_*bre 0 types conditional-statements typescript

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

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

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

我也尝试了 Exclude<any, string> 类型,但这并不完全是我想要的。

编辑

我更好地解释了我的问题:我创建了一个静态方法,如果数据是 a ,foo(data)它将执行某些操作并返回 a ,或者如果数据不是 a ,则执行其他操作并返回 a 。stringstringnumberstring

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

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,假设如果不是 a ,该foo()方法将抛出错误。我有两个案例:datastring

  • 如果该方法的用户不知道数据的类型(可能是 a string),我希望他可以使用此方法,如果不是 a ,我将返回一个错误string

  • 如果用户知道数据的类型(number例如 a ),我想告诉他这是不可能的,它不可能是 a 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)
Run Code Online (Sandbox Code Playgroud)

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

任何想法 ?

谢谢 !

Vla*_*hek 6

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

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

运行时检查属性

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

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

条件型细化

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

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

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

type Result<T> = T extends string
  ? A
  : T extends boolean
  ? B
  : T extends number
  ? C
  : never;
Run Code Online (Sandbox Code Playgroud)

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

如果没有显式设置泛型参数,则传入的 prop 是unknown默认类型。您还可以将其范围限定为输入参数可以包含的几个值,以进行更精细的控制。