isPrimitive
检查一个值是否为原始类型(primitive type)。
基础用法
typescript
import { isPrimitive } from 'radash'
console.log(isPrimitive('hello')) // true
console.log(isPrimitive(123)) // true
console.log(isPrimitive(true)) // true
console.log(isPrimitive(null)) // true
console.log(isPrimitive(undefined)) // true
console.log(isPrimitive(Symbol('test'))) // true
console.log(isPrimitive({})) // false
console.log(isPrimitive([])) // false
console.log(isPrimitive(() => {})) // false
语法
typescript
function isPrimitive(value: any): value is string | number | boolean | null | undefined | symbol
参数
value
(any): 要检查的值
返回值
返回一个布尔值,如果值是原始类型则返回 true
,否则返回 false
。同时作为TypeScript类型守卫。
示例
基本类型检查
typescript
import { isPrimitive } from 'radash'
// 字符串
console.log(isPrimitive('hello')) // true
console.log(isPrimitive('')) // true
console.log(isPrimitive('123')) // true
// 数字
console.log(isPrimitive(123)) // true
console.log(isPrimitive(0)) // true
console.log(isPrimitive(-10)) // true
console.log(isPrimitive(3.14)) // true
console.log(isPrimitive(Infinity)) // true
console.log(isPrimitive(-Infinity)) // true
console.log(isPrimitive(NaN)) // true
// 布尔值
console.log(isPrimitive(true)) // true
console.log(isPrimitive(false)) // true
// null 和 undefined
console.log(isPrimitive(null)) // true
console.log(isPrimitive(undefined)) // true
// Symbol
console.log(isPrimitive(Symbol('test'))) // true
console.log(isPrimitive(Symbol())) // true
// 非原始类型
console.log(isPrimitive({})) // false
console.log(isPrimitive([])) // false
console.log(isPrimitive(() => {})) // false
console.log(isPrimitive(new Date())) // false
console.log(isPrimitive(new RegExp(''))) // false
包装对象检查
typescript
import { isPrimitive } from 'radash'
// 包装对象不是原始类型
console.log(isPrimitive(new String('hello'))) // false
console.log(isPrimitive(new Number(123))) // false
console.log(isPrimitive(new Boolean(true))) // false
// 原始值
console.log(isPrimitive('hello')) // true
console.log(isPrimitive(123)) // true
console.log(isPrimitive(true)) // true
类型守卫使用
typescript
import { isPrimitive } from 'radash'
function processValue(value: unknown) {
if (isPrimitive(value)) {
// TypeScript 知道 value 是原始类型
console.log('Processing primitive:', value)
return String(value)
}
console.log('Processing object:', typeof value)
return JSON.stringify(value)
}
console.log(processValue('hello')) // Processing primitive: hello hello
console.log(processValue(123)) // Processing primitive: 123 123
console.log(processValue({ a: 1 })) // Processing object: object {"a":1}
数组过滤
typescript
import { isPrimitive } from 'radash'
const mixedArray = [
'hello',
123,
true,
null,
undefined,
Symbol('test'),
{},
[],
() => {},
new Date()
]
const primitives = mixedArray.filter(isPrimitive)
console.log(primitives) // ['hello', 123, true, null, undefined, Symbol(test)]
const nonPrimitives = mixedArray.filter(item => !isPrimitive(item))
console.log(nonPrimitives.length) // 4
对象属性检查
typescript
import { isPrimitive } from 'radash'
const data = {
name: 'Alice',
age: 25,
isActive: true,
email: null,
settings: { theme: 'dark' },
hobbies: ['reading', 'coding'],
greet: () => 'Hello'
}
const primitiveProperties = Object.entries(data)
.filter(([key, value]) => isPrimitive(value))
.map(([key, value]) => ({ key, value, type: typeof value }))
console.log(primitiveProperties)
// [
// { key: 'name', value: 'Alice', type: 'string' },
// { key: 'age', value: 25, type: 'number' },
// { key: 'isActive', value: true, type: 'boolean' },
// { key: 'email', value: null, type: 'object' }
// ]
数据验证
typescript
import { isPrimitive } from 'radash'
interface FormData {
name: unknown
age: unknown
email: unknown
preferences: unknown
}
function validateFormData(data: FormData) {
const errors: string[] = []
if (!isPrimitive(data.name) || typeof data.name !== 'string') {
errors.push('name must be a string')
}
if (!isPrimitive(data.age) || typeof data.age !== 'number') {
errors.push('age must be a number')
}
if (!isPrimitive(data.email) || typeof data.email !== 'string') {
errors.push('email must be a string')
}
if (isPrimitive(data.preferences)) {
errors.push('preferences must be an object')
}
return errors
}
const validData: FormData = {
name: 'Alice',
age: 25,
email: 'alice@example.com',
preferences: { theme: 'dark' }
}
const invalidData: FormData = {
name: { first: 'Alice' },
age: '25',
email: null,
preferences: 'dark'
}
console.log(validateFormData(validData)) // []
console.log(validateFormData(invalidData)) // ['name must be a string', 'age must be a number', 'email must be a string', 'preferences must be an object']
API响应处理
typescript
import { isPrimitive } from 'radash'
interface ApiResponse {
id: unknown
name: unknown
data: unknown
metadata: unknown
}
function processApiResponse(response: ApiResponse) {
const processed = {
id: isPrimitive(response.id) ? response.id : null,
name: isPrimitive(response.name) ? String(response.name) : '',
data: isPrimitive(response.data) ? response.data : {},
metadata: isPrimitive(response.metadata) ? {} : response.metadata
}
return processed
}
const response1: ApiResponse = {
id: 1,
name: 'Alice',
data: { items: [1, 2, 3] },
metadata: { created: new Date() }
}
const response2: ApiResponse = {
id: { id: 1 },
name: null,
data: 'not an object',
metadata: 'not an object'
}
console.log(processApiResponse(response1))
// { id: 1, name: 'Alice', data: {}, metadata: { created: Date } }
console.log(processApiResponse(response2))
// { id: null, name: '', data: 'not an object', metadata: {} }
配置验证
typescript
import { isPrimitive } from 'radash'
interface Config {
port: unknown
host: unknown
timeout: unknown
options: unknown
}
function validateConfig(config: Config) {
const errors: string[] = []
if (!isPrimitive(config.port) || typeof config.port !== 'number') {
errors.push('port must be a number')
}
if (!isPrimitive(config.host) || typeof config.host !== 'string') {
errors.push('host must be a string')
}
if (!isPrimitive(config.timeout) || typeof config.timeout !== 'number') {
errors.push('timeout must be a number')
}
if (isPrimitive(config.options)) {
errors.push('options must be an object')
}
return errors
}
const validConfig: Config = {
port: 3000,
host: 'localhost',
timeout: 5000,
options: { debug: true }
}
const invalidConfig: Config = {
port: '3000',
host: null,
timeout: '5s',
options: 'debug'
}
console.log(validateConfig(validConfig)) // []
console.log(validateConfig(invalidConfig)) // ['port must be a number', 'host must be a string', 'timeout must be a number', 'options must be an object']
数据库记录处理
typescript
import { isPrimitive } from 'radash'
interface DatabaseRecord {
id: number
name: unknown
value: unknown
metadata: unknown
}
function sanitizeDatabaseRecord(record: DatabaseRecord) {
return {
id: record.id,
name: isPrimitive(record.name) ? String(record.name) : '',
value: isPrimitive(record.value) ? record.value : null,
metadata: isPrimitive(record.metadata) ? {} : record.metadata
}
}
const dbRecord: DatabaseRecord = {
id: 1,
name: 'Product A',
value: 29.99,
metadata: { category: 'electronics' }
}
console.log(sanitizeDatabaseRecord(dbRecord))
// { id: 1, name: 'Product A', value: 29.99, metadata: { category: 'electronics' } }
事件处理
typescript
import { isPrimitive } from 'radash'
interface EventData {
type: unknown
payload: unknown
timestamp: unknown
}
function processEvent(event: EventData) {
const processed = {
type: isPrimitive(event.type) ? String(event.type) : 'unknown',
payload: isPrimitive(event.payload) ? event.payload : {},
timestamp: isPrimitive(event.timestamp) ? event.timestamp : Date.now()
}
return processed
}
const event: EventData = {
type: 'click',
payload: { x: 100, y: 200 },
timestamp: Date.now()
}
console.log(processEvent(event))
// { type: 'click', payload: { x: 100, y: 200 }, timestamp: 1234567890 }
序列化处理
typescript
import { isPrimitive } from 'radash'
function safeSerialize(obj: unknown): string {
if (isPrimitive(obj)) {
return JSON.stringify(obj)
}
if (obj === null) {
return 'null'
}
if (typeof obj === 'object') {
const seen = new WeakSet()
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return '[Circular Reference]'
}
seen.add(value)
}
return value
})
}
return String(obj)
}
const testData = {
string: 'hello',
number: 123,
boolean: true,
null: null,
undefined: undefined,
object: { nested: { value: 'test' } },
array: [1, 2, 3],
function: () => {}
}
Object.entries(testData).forEach(([key, value]) => {
console.log(`${key}: ${safeSerialize(value)}`)
})
类型转换
typescript
import { isPrimitive } from 'radash'
function toPrimitive(value: unknown): string | number | boolean | null | undefined {
if (isPrimitive(value)) {
return value
}
if (value === null) {
return null
}
if (typeof value === 'object') {
return JSON.stringify(value)
}
return String(value)
}
const testValues = [
'hello',
123,
true,
null,
undefined,
{ a: 1, b: 2 },
[1, 2, 3],
() => {},
new Date()
]
testValues.forEach(value => {
console.log(`${typeof value}: ${toPrimitive(value)}`)
})
深度检查
typescript
import { isPrimitive } from 'radash'
function hasOnlyPrimitives(obj: unknown): boolean {
if (isPrimitive(obj)) {
return true
}
if (obj === null || typeof obj !== 'object') {
return false
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (!hasOnlyPrimitives(obj[key])) {
return false
}
}
}
return true
}
const obj1 = {
name: 'Alice',
age: 25,
settings: {
theme: 'dark',
notifications: true
}
}
const obj2 = {
name: 'Bob',
data: { items: [1, 2, 3] },
func: () => {}
}
console.log(hasOnlyPrimitives(obj1)) // true
console.log(hasOnlyPrimitives(obj2)) // false
性能测试
typescript
import { isPrimitive } from 'radash'
function benchmarkIsPrimitive() {
const testValues = [
'hello', 123, true, null, undefined, Symbol('test'),
{}, [], () => {}, new Date(), new RegExp('')
]
const iterations = 1000000
const start = performance.now()
for (let i = 0; i < iterations; i++) {
testValues.forEach(value => {
isPrimitive(value)
})
}
const end = performance.now()
console.log(`Benchmark completed in ${end - start}ms`)
}
// benchmarkIsPrimitive() // 运行性能测试
边界值测试
typescript
import { isPrimitive } from 'radash'
// 测试边界值
const boundaryTests = [
// 字符串边界
'',
' ',
'0',
'false',
'null',
'undefined',
// 数字边界
0,
-0,
1,
-1,
Number.MAX_VALUE,
Number.MIN_VALUE,
Number.MAX_SAFE_INTEGER,
Number.MIN_SAFE_INTEGER,
Infinity,
-Infinity,
NaN,
// 布尔值
true,
false,
// null 和 undefined
null,
undefined,
// Symbol
Symbol(),
Symbol('test'),
Symbol.iterator,
// 包装对象
new String('hello'),
new Number(123),
new Boolean(true),
// 其他对象
{},
[],
() => {},
new Date(),
new RegExp(''),
new Map(),
new Set()
]
boundaryTests.forEach(value => {
console.log(`${typeof value} ${JSON.stringify(value)}: ${isPrimitive(value)}`)
})
注意事项
- 原始类型定义: 包括string、number、boolean、null、undefined、symbol
- 包装对象: 包装对象(如new String())不被认为是原始类型
- 类型守卫: 作为TypeScript类型守卫使用
- 性能: 检查速度很快,适合高频使用
- 边界值: 正确处理所有边界情况
与其他方法的区别
isPrimitive()
: 检查是否为原始类型typeof value !== 'object'
: 简单但不够准确value !== null && typeof value !== 'object'
: 排除null的对象检查typeof value === 'string' || typeof value === 'number' || ...
: 逐个类型检查
实际应用场景
- 数据验证: 验证API响应中的原始类型字段
- 类型转换: 确保值可以安全转换为原始类型
- 序列化: 处理需要序列化的数据
- 表单处理: 验证表单输入类型
- 配置验证: 验证配置中的原始类型值
- 数据库操作: 验证数据库字段类型