TypeScript: Type predicates
TypeScript 类型判断--合理的使用 is
和 type
- 这篇文章主要写在使用函数的时候确保你的参数类型正确的规范的建议。
写在最前面
- 最开始写 typescript 最困难的就是各种类型的判断,最近浏览 jsFeed 的时候看到一篇不错的文章,然后自己翻译了一下分享给大家。
- 文章中的翻译都是义译,没有逐字逐段,很多不正确的地方望指出。
Type predicates in TypeScript help you narrowing down your types based on conditionals. They’re similar to type guards, but work on functions. They way the work is, if a function returns true, change the type of the paramter to something more useful.
typescript 的类型断言帮助你更好的规范你的代码类型。类型断言一般在函数中使用(work on functions),来确保你的函数类型返回正确。
is 的使用场景
step 1
- Let’s start with a basic example. Let’s say you have a function that checks if a certain value is of type string:
- 来看一个栗子
function isString(s) {
return typeof s === 'string';
}
step 2
- Use the isString function inside another function:
- 在另外一个函数中使用上面的函数(
isString()
)
function toUpperCase(x: unknown) {
if(isString(x)) {
x.toUpperCase(); // ⚡️ x is still of type unknown
}
}
TypeScript throws an error. We can be sure that x is of type string at this point. But since the validation is wrapped in a function, the type of x does not change (as opposed to type guards). Enter type predicates.
ts 抛出了一个错误提示,我们能确信 x 是在类型判断为 string 以后再进行 toupperCase().但是由于这个检验函数(isString)被包裹在 toUpperCase()函数中,ts 在判断的时候还是抛出了错误提示。。
- Let’s tell TypeScript explicitly that if isString evaluates to true, the type of the parameter is a string:
- 使用
is
,这里让我们主动明确的告诉 ts ,在 isString() 这个函数的参数是一个 string。
// !!! 使用 is 来确认参数 s 是一个 string 类型
function isString(s): s is string {
return typeof s === 'string';
}
复制代码
- TypeScript now knows that we are dealing with strings in our toUpperCase function.
- 现在 ts 知道我们是使用
string
来处理toUpperCase
函数了。
function toUpperCase(x: unknown) {
if(isString(x)) {
x.toUpperCase(); // ✅ all good, x is string
}
}
复制代码
Narrowing down sets
缩小参数类型
- This not only helps you for unknown types, or multiple types, but also to narrow down sets within a type. Let’s have a program where you throw a dice. Every time you throw a Six, you win.
- 虽然
is
让 ts 分辨了 unknown 类型和 更多的其他类型,但是也让我们类型缩小了范围。为什么啦? - 来看一个栗子:让我们来做一个丢色子的游戏,当你丢到 6 的时候你就赢了。
step 1
代码语言:javascript复制function pipsAreValid(pips: number) {
// we check for every discrete value, as number can
// be something between 1 and 2 as well.
return pips === 1 || pips === 2 || pips === 3 ||
pips === 4 || pips === 5 || pips === 6;
}
function evalThrow(count: number) {
if (pipsAreValid(count)) {
// my types are lying