这是我的水果。ts

export type Fruit = "Orange" | "Apple" | "Banana"

现在我在进口水果。Ts在另一个typescript文件中。这是我有的

myString:string = "Banana";

myFruit:Fruit = myString;

当我这样做的时候

myFruit = myString;

我得到一个错误:

类型“string”不能赋值给类型“Orange”|“Apple”| “香蕉”

如何将字符串分配给自定义类型水果的变量?


当前回答

当传递道具到React组件时,我也遇到了类似的问题。

原因:我在myArray上的类型推断没有正确工作

https://codesandbox.io/s/type-string-issue-fixed-z9jth?file=/src/App.tsx

特别感谢Reactiflux的Brady在这个问题上的帮助。

其他回答

这个问题被标记为Angular,尽管它实际上与Angular没有任何关系。然而,有(至少)一个Angular特定的情况,你可能会意外地得到这个错误。

如果你禁用了strictNullInputTypes 如果你使用一个文字类型,比如Fruit作为@Input() 你试图将'Orange'传递给一个输入,它被解释为一个字符串。

这将在Angular 13.1中修复。

https://github.com/angular/angular/pull/38305

我知道这有点过时了,但这里可能有更好的解决方案。

当需要字符串,但希望字符串只匹配某些值时,可以使用enum。

例如:

enum Fruit {
    Orange = "Orange",
    Apple  = "Apple",
    Banana = "Banana"
}

let myFruit: Fruit = Fruit.Banana;

现在您将知道,无论如何,myFruit将始终是字符串“Banana”(或您选择的任何其他可枚举值)。这对很多事情都很有用,无论是将类似的值分组,还是将用户友好的值映射到机器友好的值,同时强制和限制编译器允许的值。

当你这样做的时候:

export type Fruit = "Orange" | "Apple" | "Banana"

…你正在创建一个名为Fruit的类型,它只能包含字面意义上的“Orange”、“Apple”和“Banana”。这种类型扩展了String,因此可以将它赋值给String。但是,String没有扩展"Orange" | "Apple" | "Banana",所以不能分配给它。String不太具体。它可以是任何字符串。

当你这样做的时候:

export type Fruit = "Orange" | "Apple" | "Banana"

const myString = "Banana";

const myFruit: Fruit = myString;

...它的工作原理。为什么?因为在这个例子中myString的实际类型是“Banana”。是的,“香蕉”就是那种类型。它是extends String,所以它是可赋值给String的。此外,当一个类型扩展Union type的任何组件时,它也扩展了Union type。在本例中,类型“Banana”扩展了“Orange”|“Apple”|“Banana”,因为它扩展了它的一个组件。因此,“香蕉”可分配给“橙子”|“苹果”|“香蕉”或水果。

如果你正在与类一起工作,你可以做以下其中之一:

示例模型:

type Fruit = 'Apple' | 'Banana';

interface ClassWithFruit  {
  fruit: Fruit;
}

实现模型的类,这里有三个选项:

class MyClass implements ClassWithFruit {
  // option 1
  fruit = 'Apple' as const;

  // option 2
  fruit = <const>'Apple';
  
  // option 3
  readonly fruit = 'Apple';
}

Typescript 3.4引入了新的'const'断言

您现在可以防止文字类型(例如。'橙色'或'红色')被“拓宽”为使用所谓的const断言的类型字符串。

你将能够做到:

let fruit = 'orange' as const;  // or...
let fruit = <const> 'orange';

然后它就不会再变成字符串了,这就是问题的根源。

你也可以在整个对象上这样做:

let animals = [ { species: 'dog' }, { species: 'cat' } ] as const;

type firstAnimal = (typeof animals)[0]['species'];  // string literal 'dog'

额外提示:你也可以使用<const> false或<const> true来表示一个必须为真或假的布尔值。这在有歧视的工会中有时是有用的。你一看到就知道了。