reactjs - 尝试创建类型检查器实用程序,但不能不出现类型错误
问题描述
我有一个我想使用的 util 函数,它将返回一个布尔值,说明一个值是否等于某种类型:
const valueIsOfType = <T>(value: T, type: string):boolean => typeof(value) === type ? true : false;
但是,当我在代码中将它用作三元运算符的条件时,如下所示:
const foo: string | JSX.Element = "bar";
return valueIsOfType(title, "string") ? truncateText(title, 18) : title;
注意:函数声明为truncateText(text, maxLength)
;
const truncateText = (text: string, maxLength: number):string => {
if(text.length >= maxLength) return text.slice(0, maxLength) + "..."
else return text;
};
我在调用行收到以下类型错误valueIsOf
:
“'string | JSX.Element' 类型的参数不可分配给'string' 类型的参数。'JSX.Element' 类型不可分配给'string' 类型。”
我认为这是因为 TypeScipt 无法判断我正在使用此函数检查类型,因此它会触发类型错误以防止处理不匹配的类型truncateText;
。
有没有一种方法可以让我使用这个工具,而不必typeof(value) === type ? true : false;
为我想要检查的每种类型手动执行?为了便于阅读,我想使用这个工具或类似的东西。
解决方案
我猜你想valueIsOfType()
充当用户定义的类型保护函数,编译器将boolean
返回值视为其参数之一是否属于某种类型的证据。如果是这样,您需要将返回类型注释为类型谓词,例如value is string
.
编译器看不到typeof value === type
并自动推断该函数本身是一个类型保护。有一个未解决的问题microsoft/TypeScript#16069要求提供这样的功能,但目前它不是语言的一部分。
在任何情况下,您都可以创建一个通用版本valueIsOfType()
函数,它有望涵盖 JavaScripttypeof
运算符的所有可能结果以及对测试对象的影响:
interface TypeofResults {
string: string,
number: number,
bigint: bigint,
boolean: boolean,
symbol: symbol,
undefined: undefined,
object: object | null,
function: Function
}
const valueIsOfType =
<K extends keyof TypeofResults>(value: any, type: K): value is TypeofResults[K] =>
typeof value === type
该TypeofResults
接口用作从结果typeof
和受保护类型的映射。其中大部分都很简单,因为 TypeScript 类型名称与从typeof
. 有一些是不同的......如果typeof value === "object"
thenvalue
是 TypeScriptobject
类型,或者它是null
,它不被认为可以分配给object
. Function
TypeScript 的未指定函数类型用大写字母调用F
。
该valueIsOfType()
函数是泛型的K
,参数的类型,返回类型是一个类型谓词,将参数从(不需要是泛型的)type
缩小到对应的属性类型从。因此,如果您调用,返回类型将是类型谓词。value
any
TypeofResults
valueIsOfType(anyValue, "string")
anyValue is string
你可以看到它有效:
function test(foo: string | number | Date) {
if (valueIsOfType(foo, "string")) {
console.log(foo.toUpperCase()); // foo seen to be string here
} else if (valueIsOfType(foo, "number")) {
console.log(foo.toFixed(2)); // foo seen to be number here
} else {
console.log(foo.toUTCString()) // foo seen to be Date here
}
}
test("hello"); // HELLO
test(Math.PI); // 3.14
test(new Date()); // Sat, 12 Sep 2020 02:22:01 GMT
推荐阅读
- oracle - 按下按钮时触发器引发未处理的异常 ora-01401
- ssh - SSH 到 ECS Fargate 任务中的 docker 容器
- json - 我正在尝试将 json 对象转换为 csv 对象
- mysql - 如何在postgres中将两个select语句作为两列
- javascript - 在 Angular 6 中保留 form.reset() 上的选择字段占位符
- c - 使用 c 中的 dll 在 Labview 中处理图像
- php - 注入控制器中的函数有多少模型名称[基于问题]?
- unit-testing - Azure Dev Ops 构建管道 xunit 嵌套失败(.net 核心)
- java - 空 GETINPUTSTREAM
- java - Spring STOMP WebSocket 会话断开处理程序/重新连接处理