文章目录
- 前言
- 一、一个示例
- 二、示例目的
- 1、功能描述
- 2、主要区别
- 3、代码实现
- 总结
前言
本片文章主要是在写ts时遇到不知道类型,很容易就想到用any可以解决一切,但这样写并不好。所以今天就总结学习一下,比较好的处理任意类型的unknown。
一、一个示例
光看效果图可能看不懂,跟着代码解析一起看。
二、示例目的
1、功能描述
这个示例主要实现了,用any类型和unknown类型的区别。
- 切换输入框类型
- 切换结果函数接受参数类型
- 输入两个内容,进行结果类型判断
首先可以看到当选择输入框类型为text或者number时,并且函数接受参数类型为any时,没有任何报错和提示。
当把类型切换为unknown类型时,需要添加参数类型判断,否则会有错误提示。可以先来看看ts本身的错误提示:
意思时,这个参数类型是unknown类型,是未知的类型。如果你继续执行后面的代码,可能会有报错风险。
所以需要你提前添加类型判断。
例如这样:
const concatenateUnknownString = (str1: unknown, str2: unknown) => {if (typeof str1 === 'string' && typeof str2 === 'string') {return str1 + str2;} else {return `err type args1${typeof str1} args2 ${typeof str2}`;}
}
这样明确的进行判断参数类型,就可以避免运行时报错。保证类型安全。
2、主要区别
- any可以接受任何类型的值,而unknown也可以接受任何类型的值,但需要进行类型检查或类型断言才能使用。
- 具体来说,any类型可以用于任何变量或函数参数,它表示该变量或参数可以是任何类型的值。
上面的代码展示了,类型判断,以下为修改类型断言形式。
const concatenateUnknownString = (str1: unknown, str2: unknown) => {return `${str1} + ${str2}`return str1 as string + str2return Number(str1) + Number(str2)
}
3、代码实现
1、主体实现
定义:
const [textStr, setTestStr] = useState("")
const [textType, setTextType] = useState("text")
const [textTypeCheck, setTextTypeCheck] = useState<{ [key: string]: boolean }>({ text: true, number: false })
const [typeTsCheck, setTypeTsCheck] = useState<{ [key: string]: boolean }>({ any: true, unknown: false })
const [inputObj, setInputObj] = useState<inputType>({first: "",second: ""
})
const [typeTs, setTypeTs] = useState("any")
这里定义了radio的选中状态,textTypeCheck和textTsCheck,分别控制输入框文本类型和参数类型的状态。
主要逻辑部分:
const tapFn = () => {if (typeTs === "any") {setTestStr(concatenateAnyString(inputObj.first, inputObj.second))} else {setTestStr(concatenateUnknownString(inputObj.first, inputObj.second))}
}const onChangeFn = (e: ChangeEvent<HTMLInputElement>) => {setTextTypeCheck((pre) => {for (let item of Object.keys(pre)) {console.log(item)pre[item] = false}return { ...pre, [e.target.defaultValue]: e.target.checked }})setTextType(e.target.defaultValue)
}const onChangeTypeFn = (e: ChangeEvent<HTMLInputElement>) => {setTypeTsCheck((pre) => {for (let item of Object.keys(pre)) {pre[item] = false}return { ...pre, [e.target.defaultValue]: e.target.checked }})setTypeTs(e.target.defaultValue)
}const onInputFn = (value: string, valueKey: string) => {setInputObj({...inputObj,[valueKey]: textType === 'number' ? +value : value})
}
tapFn控制值得到的结果的Result部分。
onChangeFn和onChangeTypeFn为控制radio状态。
onInputFn为输入值。
总结
所以当无法确定一个变量的类型时,应该优先使用 unknown 类型,因为它能更好的保证类型安全性。除非有特殊情况需要,否则应该避免使用 any 类型。