typescript - Type inference from array of elements
问题描述
I have a code similar to this:
const x = 'a';
const y = 1;
const arr1 = [x, y]; // -> (string | number)[]
const arr2: [string, number] = [x, y]; // -> [string, number]
I cant understand why TypeScript's type inference is getting (string | number)[]
instead of [string, number]
.
Do I have to specifically tell TypeScript arr2: [string, number]
or maybe there is easier way?
Above example is simple, but problem is more annoying with this:
function useFormField() {
const [field, setField] = useState('');
const [fieldError, setFieldError] = useState(false);
const fieldRef = useRef<HTMLInputElement>(null);
return [field, setField, fieldError, setFieldError, fieldRef];
}
Type inference: (string | boolean | React.RefObject<HTMLInputElement> | React.Dispatch<React.SetStateAction<string>> | React.Dispatch<React.SetStateAction<boolean>>)[]
So to make it what I need I have to define return type manually:
function useFormField(): [string, React.Dispatch<React.SetStateAction<string>>, boolean, React.Dispatch<React.SetStateAction<boolean>>, React.RefObject<HTMLInputElement>]{
// ...
}
解决方案
Typescript 通常不会为数组文字推断元组。有几种方法可以在没有显式类型的情况下推断元组(具有显式类型的版本也可以正常工作,但您可能希望避免重复)。
选项 1:使用通用函数
如果我们有一个其余参数类型的类型参数,Typescript 将推断元组
function tuple<T extends any[]>(...a: T) {
return a
}
let r = tuple(1,2,3) // [number, number, number]
另一种选择,如果我们想保留数组字面量语法是使用既是数组又是单元素元组的约束(any | any[]
),单元素元组将提示编译器我们想要一个元组,但数组将允许元组为任意大小:
function tuple<T extends [any] | any[]>(a: T) {
return a
}
let r = tuple([1,2,3]) // [number, number, number]
选项 2:使用as const
(用于 TS 3.4 及更高版本)
3.4 添加所谓的const 断言。这有几个副作用,其中之一是推断元组。另一种是推断只读元组并推断所有文字的文字类型,这可能会使此解决方案不像函数那样通用,但您可以根据需要混合和匹配:
let r = [1,2,3] as const // [1,2,3]
推荐阅读
- c# - Selenium - StaleElementReferenceException (Chromedriver 80)
- dynamics-crm-365 - 从 CRM 迁移到云 365。Ribbon Workbench 导出解决方案
- azure - AzureStorageEmulator 5.1 无法启动
- mysql - SQL 将输出限制为多个结果
- angular - 从版本 2.9.2 更新到 3.7.5 后出现打字稿错误
- android - 如何动态更改底部导航项文本?
- css - 带有滚动角的粘性侧边栏
- go - 为什么golang对字节切片使用括号,对字符串切片使用括号?
- elasticsearch - 在 Kibana 中可视化 Kafka 日志
- javascript - 如何访问json数据(嵌套数组)