关于typescript:搞懂TypeScript中的类型断言和使用场景

13次阅读

共计 2954 个字符,预计需要花费 8 分钟才能阅读完成。

TypeScript 的类型断言看起来概念比较简单,然而对于刚接触 TypeScript 的使用者,可能对应用场景短少意识,心愿本文能够帮忙你更理解类型断言。

当你应用一个值,然而 TypeScript 不晓得具体类型 或者 TypeScript 记录的类型没有方法满足应用要求时,能够应用类型断言来明确指定为本人想要应用的类型。

语法:

类型断言有两种形式:

  1. 应用 <> 语法
  2. 应用 as 关键字

<> 会和 JSX 语法抵触,个别应用 as

咱们来看几个类型断言的示例

1. 对于通过标签获取的 DOM,TypeScript 能够推断出类型,然而对于其余形式,TypeScript 无奈推断,咱们能够应用类型断言来明确指定元素类型。

const aEle = document.querySelector('a') // HTMLAnchorElement | null
const canvasEle = document.querySelector('#my_canvas') as HTMLCanvasElement
React.useEffect(() => {if (props.autoFocus) {
    const $this = ref.current as HTMLInputElement;
    ...
  }
}, []);

AntD 中的示例:ActionButton.tsx

2. 对于空对象占位,能够断言为特定类型,以获取正确的代码提醒和类型推断

const [user, setUser] = useState<User | null>(null);
setUser(newUser);
const [user, setUser] = useState<User>({} as User);
setUser(newUser);

const 断言

const 断言通知编译器为表达式推断出它能推断出的最窄或最特定的类型,而不是通用类型。

// point 变成一个 readonly 数组类型,批改数组内容会提醒谬误。let point = [3, 4] as const; // readonly [3, 4]
point[0] = 1 // Error

咱们来看一个代码示例:

function useDarkMode() {const [mode, setMode] = React.useState<'dark' | 'light'>(() => {
    // ...
    return 'light'
  })
  ...
  return [mode, setMode] as const
}
​
const [mode, setMode] = useDarkMode() // 伪代码,hook 须要再函数组件中应用

咱们来比照一下 mode 和 setMode 应用 as const 之后的差异:

在应用 const 断言之前,mode 和 setMode 类型为:

const mode: "dark" | "light" | React.Dispatch<React.SetStateAction<"dark" | "light">>
const setMode: "dark" | "light" | React.Dispatch<React.SetStateAction<"dark" | "light">>

调用 setMode 时,会提醒谬误,因为 ‘dark’ | ‘light’ 并不是可调用类型。

应用 as const 断言之后,mode 和 setMode 类型为:

const mode: "dark" | "light"
const setMode: React.Dispatch<React.SetStateAction<"dark" | "light">>

调用传参谬误时,也会有类型谬误提醒。

能够看到,对于数组来说,每个元素的类型是整个数组元素类型的联结类型

const arr = [1,'2'] 
// const arr: (string | number)[]

应用 as const 断言之后,数组会变成 readonly 数组且 每个元素有了本人的特定类型,也有了更好的谬误提醒。

再来看一个 rxjs 中的示例:fromEvent.ts

// These constants are used to create handler registry functions using array mapping below.
// 这些常量用于应用上面的数组映射创立处理程序注册表函数
const nodeEventEmitterMethods = ['addListener', 'removeListener'] as const;
const eventTargetMethods = ['addEventListener', 'removeEventListener'] as const;
const jqueryMethods = ['on', 'off'] as const;

应用 as const 之后,类型检测更为严格:

  • readonly 数组,每个元素都有本人的字面量类型,无奈调整为其余值,杜绝被意外批改的可能
  • 在拜访数组元素或进行数组解构时,因数组长度固定,防止越界,更不容易出错

const 断言和 typeof 搭配应用:useSelection.tsx

字符串应用 as const 之后,变量就有了字面量类型,typeof 操作符能够提取其字面量类型应用。

export const SELECTION_ALL = 'SELECT_ALL' as const;
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
​
export type INTERNAL_SELECTION_ITEM =
  | SelectionItem
  | typeof SELECTION_ALL
  | typeof SELECTION_INVERT;

躲避类型查看

TypeScript 只容许类型断言为一个更具体或者更不具体的类型,这个规定能够阻止一些谬误的强制类型转换:

const x = "hello" as number;
// Error:将 'string' 类型转换为 'number' 类型可能是一个谬误,因为这两种类型都没有充沛重叠。如果这是成心的,请先将表达式转换为“unknown”。

咱们再来看一个 Antd 中的应用示例: back-top

React.useEffect(() => {bindScrollEvent();
  return () => {if (scrollEvent.current) {scrollEvent.current.remove();
    }
    (handleScroll as any).cancel();};
}, [props.target]);

handleScroll 是一个函数,然而其余文件中被减少了 cancel 属性,此处间接调用 cancel 办法,TypeScript 会提醒谬误,能够断言为 any 来躲避 TypeScript 的类型查看

双重断言

对于咱们曾经明确的变量类型,如果不存在重叠,能够先断言为一个宽泛的类型(any、unknown),再断言为一个具体的类型。

// es default export should use const instead of let
const ExportTypography = (RefTypography as unknown) as React.FC<TypographyProps>;

Typography

留神:当应用断言时,应该确保你理解以后值的类型,防止出错。对于能够收窄的类型,尽量应用类型收窄而非断言。

正文完
 0