TypeScript 被忽视的部分
一些被误解的 TypeScript 类型
如何表示一个值是任意值:unknown
尽管 any
和 unknown
都能表示任意值,但 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>
Object
、object
、{}
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>>;