🐾
被忽视的 TypeScript

TypeScript 被忽视的部分

一些被误解的 TypeScript 类型

如何表示一个值是任意值unknown

尽管 anyunknown 都能表示任意值,但 any 完全放弃了类型检查,你对一个 any 类型的值做任何操作 TypeScript 都不会校验。 而对 unknown 类型的值做操作时,TypeScript 会检查你的操作是否安全。

比如下面的例子:

const foo: unknown = { a: 1 }
 
console.log(foo.a) // 报错:对象的类型为“未知”。
const bar: any = { b: 1 }
 
console.log(bar.b) // 不进行类型检查,不报错

简而言之 unknown 是安全的,any 是不安全的。

如何表示一个值是任意对象

使用泛型类型 Record 描述一个具有任意字符串键和任意类型值的对象。

Record<string, unknown>

也可以使用字面量类型,这里使用了索引签名 [key: string] 表示任意字符串键。

{
    [key: string]: unknown;
};

字面量类型比泛型类型更容易扩展,比如你要添加一个数字类型属性 a

使用字面量类型:

{
    [key: string]: unknown;
    a: number;
};

而泛型类型则需要使用联合类型:

Record<string, unknown> & { a: number }
如何表示一个值是空对象
Record<string, never>
Objectobject{}

object 是非原始值的意思。

{} 表示 Object 任何非空值。

React.Component<{}, State>

// 以下三者等价,都表示非空值
interface AnyNonNullishValue {}
// type AnyNonNullishValue = {}
// type AnyNonNullishValue = Object
export declare interface AppProps {
  children?: React.ReactNode // best, accepts everything React can render
  childrenElement: React.JSX.Element // A single React element
  style?: React.CSSProperties // to pass through style props
  onChange?: React.FormEventHandler<HTMLInputElement> // form events! the generic parameter is the type of event.target
  //  more info: https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#wrappingmirroring
  props: Props & React.ComponentPropsWithoutRef<'button'> // to impersonate all the props of a button element and explicitly not forwarding its ref
  props2: Props & React.ComponentPropsWithRef<MyButtonWithForwardRef> // to impersonate all the props of MyButtonForwardedRef and explicitly forwarding its ref
}
为什么不推荐使用 React.FC

Function 任何函数类型

setState: React.Dispatch<React.SetStateAction<number>>;

type 和 interface 的选择


MIT 2024 © Binghuis