Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 类型脚本类型';字符串';不可分配给类型_Javascript_Typescript_Angular - Fatal编程技术网

Javascript 类型脚本类型';字符串';不可分配给类型

Javascript 类型脚本类型';字符串';不可分配给类型,javascript,typescript,angular,Javascript,Typescript,Angular,这是我的水果 export type Fruit = "Orange" | "Apple" | "Banana" 现在我正在另一个typescript文件中导入fruit.ts。这是我的 myString:string = "Banana"; myFruit:Fruit = myString; 当我这样做的时候 myFruit = myString; 我得到一个错误: 类型“string”不可分配给类型“Orange”|“Apple”| “香蕉” 如何将字符串分配给自定义类型Fruit的

这是我的水果

export type Fruit = "Orange" | "Apple" | "Banana"
现在我正在另一个typescript文件中导入fruit.ts。这是我的

myString:string = "Banana";

myFruit:Fruit = myString;
当我这样做的时候

myFruit = myString;
我得到一个错误:

类型“string”不可分配给类型“Orange”|“Apple”| “香蕉”

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

您需要:

还请注意,使用时只需使用一个
|

编辑 正如@Simon_Weaver在另一个答案中提到的,现在可以将其断言为
const

let fruit = "Banana" as const;

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

如果需要字符串,但希望该字符串仅与某些值匹配,则可以使用

例如:

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

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

执行此操作时:

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

const myString = "Banana";

const myFruit: Fruit = myString;
…您正在创建一个名为
水果
的类型,该类型只能包含文本
“橙色”
“苹果”
“香蕉”
。此类型扩展了
字符串
,因此可以将其分配给
字符串
。但是,
字符串
不扩展
“橙色”|“苹果”|“香蕉”
,因此无法将其分配给它<代码>字符串不太具体。它可以是任何字符串

执行此操作时:

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

const myString = "Banana";

const myFruit: Fruit = myString;

…它起作用了。为什么?因为本例中
myString
的实际类型是
“香蕉”
。是的,
“香蕉”
类型。它扩展了
String
,因此可以分配给
String
。此外,类型在扩展其任何组件时扩展了联合类型。在本例中,
“Banana”
,类型扩展了
“Orange”|“Apple”|“Banana”
,因为它扩展了它的一个组件。因此,
“香蕉”
可分配给
“橙色”|“苹果”|“香蕉”
水果

有几种情况会导致此特定错误。对于OP,有一个值明确定义为字符串。因此,我必须假设这可能来自下拉列表、web服务或原始JSON字符串

在这种情况下,唯一的解决方案是将
水果串
水果串转换为水果串
(参见其他答案)。在编译时,您永远无法在这方面有所改进。[编辑:请参阅我关于
]的其他答案]

但是,在代码中使用从未打算为string类型的常量时,很容易遇到同样的错误。我的回答集中在第二种情况:


首先:为什么“神奇”字符串常量通常比枚举更好?

  • 我喜欢字符串常量相对于枚举的外观-它紧凑且“javascripty”
  • 如果您正在使用的组件已经使用了字符串常量,则更有意义
  • 仅为了获得枚举值而必须导入“枚举类型”本身可能会很麻烦
  • 无论我做什么,我都希望它是编译安全的,因此如果我从联合类型中添加或删除有效值,或者键入错误,那么它必须给出一个编译错误
幸运的是,当您定义:

导出类型FieldErrorType='none'|'missing'|'invalid'

…您实际上是在定义类型的联合,其中,
'missing'
实际上是一个类型

如果我的typescript中有一个类似于
'banana'
的字符串,而编译器认为它是一个字符串,而我真的希望它是
banana
类型,那么我经常会遇到“not assignable”错误。编译器的智能程度取决于代码的结构

下面是我今天遇到这个错误的一个例子:

// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
当我发现
'invalid'
'banana'
可能是一个类型或字符串时,我意识到我可以将字符串断言为该类型。本质上是将其自身转换为,并告诉编译器不,我不希望它是字符串

// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
这不是编译时安全的:

 <FieldErrorType> 'invalidddd';  // COMPILER ALLOWS THIS - NOT GOOD!
 <FieldErrorType> 'dog';         // COMPILER ALLOWS THIS - NOT GOOD!
 'dog' as FieldErrorType;        // COMPILER ALLOWS THIS - NOT GOOD!
我们可以将整个对象“断言”为
FieldErrorType
,如下所示:

 <'banana'> 'banan';    // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
  fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
fieldErrors:[{field:'number',error:'invalid'}]
然后我们就不必执行
“无效”

但是打字错误呢?不只是断言右边属于该类型的内容。在这种情况下不是这样-幸运的是,如果您这样做,编译器会抱怨,因为它足够聪明,知道这是不可能的:

  fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
fieldErrors:[{field:'number',error:'dog'}]
Typescript引入了新的“const”断言

您现在可以使用所谓的
const
断言防止文本类型(例如
'orange'
'red'
)被“加宽”为类型
字符串

您将能够做到:

let fruit = 'orange' as const;  // or...
let fruit = <const> 'orange';
let fruit='orange'作为常量;//或
让水果=橙色;
然后它就不会再把自己变成
字符串了
——这是问题的根源


额外提示:您还可以使用
false
true
来表示必须为true或false的布尔值。这在某些情况下很有用。当您看到它时,您就会知道它。

如果您在模拟数据时强制转换为
dropdownvalue[]
,请将其组合为具有值和显示属性的对象数组

示例

[{'value': 'test1', 'display1': 'test display'},{'value': 'test2', 'display': 'test display2'},]

我也面临同样的问题,我做了如下c
let fruit = 'orange' as const;  // or...
let fruit = <const> 'orange';
[{'value': 'test1', 'display1': 'test display'},{'value': 'test2', 'display': 'test display2'},]
\apollo-client\core\watchQueryOptions.d.ts
export interface QueryBaseOptions<TVariables = OperationVariables> {
    query: **DocumentNode**;
export interface QueryBaseOptions<TVariables = OperationVariables> {
    query: **any**;
  // in foo.ts
  export type ToolbarTheme = {
    size: 'large' | 'small',
  };

  // in bar.ts
  import { ToolbarTheme } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}

  // Here you will get the following error: 
  // Type 'string' is not assignable to type '"small" | "large"'.ts(2322)
  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size })
  ));
  // in foo.ts
  export type ToolbarThemeSize = 'large' | 'small';
  export type ToolbarTheme = {
    size: ToolbarThemeSize
  };

  // in bar.ts
  import { ToolbarTheme, ToolbarThemeSize } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}
  function getToolbarSize(): ToolbarThemeSize  {/* ... */}

  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size: size as ToolbarThemeSize })
  ));
  // in foo.ts
  export type ToolbarTheme = {
    size: 'large' | 'small'
  };

  // in bar.ts
  import { ToolbarTheme } from './foo.ts';
  function useToolbarTheme(theme: ToolbarTheme) {/* ... */}

  ['large', 'small'].forEach(size => (
    useToolbarTheme({ size } as ToolbarTheme)
  ));
myObject.abcOrD = myStringVar as any;
export type Fruit = "Orange" | "Apple" | "Banana"
export type FruitArray = Fruit[];

const someFruits= ["Banana"];

const workingFruits: FruitArray = ["Orange", "Apple"]; // Works

// Even orange and apple show: Type 'string' is not assignable to type Fruit
const brokenAllFruits: FruitArray = [...someFruits, "Orange", "Apple"]; 

// As const is needed in the spread array
const someConstFruits= ["Banana" as const];
const workingAllFruits: FruitArray = [...someConstFruits, "Orange", "Apple"]; // Works