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響應中的原始類型字段
- 類型轉換: 確保值可以安全轉換為原始類型
- 序列化: 處理需要序列化的數據
- 表單處理: 驗證表單輸入類型
- 配置驗證: 驗證配置中的原始類型值
- 數據庫操作: 驗證數據庫字段類型