TypeScript 说字符串无效,即使它在联合中?

Leo*_*ang 15 javascript typescript reactjs

我从 AWS Amplify 教程中复制了以下内容:

const styles = {
  container: { flexDirection: 'column' },
  ...
};

<div style={styles.container}>
Run Code Online (Sandbox Code Playgroud)

但我得到:

Type '{ flexDirection: string; }' is not assignable to type 'CSSProperties'.
  Types of property 'flexDirection' are incompatible.
    Type 'string' is not assignable to type '"column" | "inherit" | "-moz-initial" | "initial" | "revert" | "unset" | "column-reverse" | "row" | "row-reverse" | undefined'.
Run Code Online (Sandbox Code Playgroud)

我可以通过将样式内联放置来轻松解决这个问题,但我很好奇为什么 TypeScript 认为这是一个错误。这是一个非常基本的示例,我很惊讶 TS 在这方面失败了,所以这让我对使用 TS 持谨慎态度。

TLa*_*add 19

这是一个TS Playground,说明了该问题和四种可能的解决方案:

type FlexDirection = "column" | "inherit" | "-moz-initial" | "initial" | "revert" | "unset" | "column-reverse" | "row" | "row-reverse" | undefined;

type Styles = {
    container: {
        flexDirection: FlexDirection
    }
}

function doStuff(a: Styles) { }

const stylesDoesNotWork = {
    container: { flexDirection: 'column' }
};

const stylesWithCast = {
  container: { flexDirection: 'column' as 'column' }
}

const stylesFieldConst = {
    container: { flexDirection: 'column' } as const
};

const stylesConst = {
    container: { flexDirection: 'column' }
} as const;

doStuff(stylesDoesNotWork);
doStuff(stylesWithCast);
doStuff(stylesFieldConst);
doStuff(stylesConst);
Run Code Online (Sandbox Code Playgroud)

默认情况下,TypeScript 将为string您声明的对象推断类型。您可能会在某处对其进行变异并更改值,在这种情况下,文字类型将不正确。因此,修复它的基本选项是:

  • 手动注释变量,以便 TypeScript 不会推断字符串。
  • 添加as 'column'强制转换以告诉 TypeScript 使用文字类型。
  • 在字段或整个对象上使用as const来告诉 TypeScript 该字段不允许更改,这允许 Typescript 推断文字值。