Skip to content

isFloat

檢查值是否為浮點數類型。

基礎用法

typescript
import { isFloat } from 'radash'

console.log(isFloat(3.14))        // true
console.log(isFloat(42))          // false
console.log(isFloat('3.14'))      // false
console.log(isFloat(NaN))         // false
console.log(isFloat(Infinity))    // false

語法

typescript
function isFloat(value: any): value is number

參數

  • value (any): 要檢查的值

返回值

返回一個布爾值,如果值是浮點數則返回 true,否則返回 false。同時作為TypeScript類型守衛。

示例

基本類型檢查

typescript
import { isFloat } from 'radash'

// 浮點數
console.log(isFloat(3.14))        // true
console.log(isFloat(-2.5))        // true
console.log(isFloat(0.0))         // true
console.log(isFloat(1.0))         // true

// 整數
console.log(isFloat(42))          // false
console.log(isFloat(0))           // false
console.log(isFloat(-10))         // false

// 字符串
console.log(isFloat('3.14'))      // false
console.log(isFloat('42'))        // false
console.log(isFloat(''))          // false

// 其他類型
console.log(isFloat(null))        // false
console.log(isFloat(undefined))   // false
console.log(isFloat(true))        // false
console.log(isFloat(false))       // false
console.log(isFloat([]))          // false
console.log(isFloat({}))          // false

特殊數值檢查

typescript
import { isFloat } from 'radash'

// NaN
console.log(isFloat(NaN))         // false

// 無窮大
console.log(isFloat(Infinity))    // false
console.log(isFloat(-Infinity))   // false

// 最大/最小值
console.log(isFloat(Number.MAX_VALUE))    // false
console.log(isFloat(Number.MIN_VALUE))    // true (最小正浮點數)
console.log(isFloat(Number.MAX_SAFE_INTEGER)) // false
console.log(isFloat(Number.MIN_SAFE_INTEGER)) // false

邊界值檢查

typescript
import { isFloat } from 'radash'

// 接近整數的浮點數
console.log(isFloat(1.0000000000000001)) // true
console.log(isFloat(1.0))                 // true
console.log(isFloat(1.0000000000000000)) // true

// 科學計數法
console.log(isFloat(1.23e-4))    // true
console.log(isFloat(1.23e+4))    // true
console.log(isFloat(1.23E4))     // true

// 十六進制
console.log(isFloat(0x1.23p4))   // true
console.log(isFloat(0x1.23P4))   // true

類型守衛使用

typescript
import { isFloat } from 'radash'

function processNumber(value: unknown) {
  if (isFloat(value)) {
    // TypeScript 知道 value 是浮點數
    console.log(`Processing float: ${value}`)
    return value * 2
  }
  
  if (typeof value === 'number') {
    // 處理整數
    console.log(`Processing integer: ${value}`)
    return value * 2
  }
  
  console.log('Not a number')
  return null
}

console.log(processNumber(3.14))  // Processing float: 3.14 6.28
console.log(processNumber(42))    // Processing integer: 42 84
console.log(processNumber('abc')) // Not a number null

數組過濾

typescript
import { isFloat } from 'radash'

const mixedArray = [1, 2.5, 3, 4.7, '5', 6.0, 7, 8.9, null, undefined]

const floats = mixedArray.filter(isFloat)
console.log(floats) // [2.5, 4.7, 6.0, 8.9]

const nonFloats = mixedArray.filter(item => !isFloat(item))
console.log(nonFloats) // [1, 3, '5', 7, null, undefined]

對象屬性檢查

typescript
import { isFloat } from 'radash'

const data = {
  price: 19.99,
  quantity: 5,
  rating: 4.5,
  id: 123,
  name: 'Product A',
  weight: 2.5,
  isAvailable: true
}

const floatProperties = Object.entries(data)
  .filter(([key, value]) => isFloat(value))
  .map(([key, value]) => ({ key, value }))

console.log(floatProperties)
// [
//   { key: 'price', value: 19.99 },
//   { key: 'rating', value: 4.5 },
//   { key: 'weight', value: 2.5 }
// ]

表單驗證

typescript
import { isFloat } from 'radash'

interface FormData {
  price: unknown
  quantity: unknown
  discount: unknown
}

function validateForm(data: FormData) {
  const errors: string[] = []
  
  if (!isFloat(data.price)) {
    errors.push('Price must be a valid decimal number')
  }
  
  if (typeof data.quantity !== 'number' || !Number.isInteger(data.quantity)) {
    errors.push('Quantity must be a whole number')
  }
  
  if (data.discount !== null && data.discount !== undefined) {
    if (!isFloat(data.discount)) {
      errors.push('Discount must be a valid decimal number')
    }
  }
  
  return errors
}

console.log(validateForm({
  price: 19.99,
  quantity: 5,
  discount: 0.1
})) // []

console.log(validateForm({
  price: '19.99',
  quantity: 5.5,
  discount: '10%'
})) // ['Price must be a valid decimal number', 'Quantity must be a whole number', 'Discount must be a valid decimal number']

API響應處理

typescript
import { isFloat } from 'radash'

interface ApiResponse {
  id: number
  price: unknown
  rating: unknown
  score: unknown
}

function processApiResponse(response: ApiResponse) {
  const processed = {
    id: response.id,
    price: isFloat(response.price) ? response.price : 0,
    rating: isFloat(response.rating) ? response.rating : 0,
    score: isFloat(response.score) ? response.score : 0
  }
  
  return processed
}

const response1: ApiResponse = {
  id: 1,
  price: 29.99,
  rating: 4.5,
  score: 85.7
}

const response2: ApiResponse = {
  id: 2,
  price: '29.99',
  rating: '4.5',
  score: null
}

console.log(processApiResponse(response1))
// { id: 1, price: 29.99, rating: 4.5, score: 85.7 }

console.log(processApiResponse(response2))
// { id: 2, price: 0, rating: 0, score: 0 }

數學計算

typescript
import { isFloat } from 'radash'

function calculateAverage(values: unknown[]): number {
  const validFloats = values.filter(isFloat)
  
  if (validFloats.length === 0) {
    return 0
  }
  
  const sum = validFloats.reduce((acc, val) => acc + val, 0)
  return sum / validFloats.length
}

const measurements = [1.5, 2.3, 3, 4.7, 'invalid', 5.1, null, 6.2]

console.log(calculateAverage(measurements)) // 3.76

數據庫查詢結果處理

typescript
import { isFloat } from 'radash'

interface DatabaseRecord {
  id: number
  value: unknown
  amount: unknown
  percentage: unknown
}

function sanitizeDatabaseRecord(record: DatabaseRecord) {
  return {
    id: record.id,
    value: isFloat(record.value) ? record.value : 0,
    amount: isFloat(record.amount) ? record.amount : 0,
    percentage: isFloat(record.percentage) ? record.percentage : 0
  }
}

const dbRecord: DatabaseRecord = {
  id: 1,
  value: 123.45,
  amount: '67.89',
  percentage: null
}

console.log(sanitizeDatabaseRecord(dbRecord))
// { id: 1, value: 123.45, amount: 0, percentage: 0 }

配置文件處理

typescript
import { isFloat } from 'radash'

interface Config {
  timeout: unknown
  retryDelay: unknown
  maxRetries: unknown
  threshold: unknown
}

function validateConfig(config: Config) {
  const errors: string[] = []
  
  if (!isFloat(config.timeout)) {
    errors.push('timeout must be a decimal number')
  }
  
  if (!isFloat(config.retryDelay)) {
    errors.push('retryDelay must be a decimal number')
  }
  
  if (typeof config.maxRetries !== 'number' || !Number.isInteger(config.maxRetries)) {
    errors.push('maxRetries must be a whole number')
  }
  
  if (!isFloat(config.threshold)) {
    errors.push('threshold must be a decimal number')
  }
  
  return errors
}

const validConfig: Config = {
  timeout: 5000.5,
  retryDelay: 1000.0,
  maxRetries: 3,
  threshold: 0.95
}

const invalidConfig: Config = {
  timeout: '5000',
  retryDelay: '1000ms',
  maxRetries: 3.5,
  threshold: '95%'
}

console.log(validateConfig(validConfig))   // []
console.log(validateConfig(invalidConfig)) // ['timeout must be a decimal number', 'retryDelay must be a decimal number', 'maxRetries must be a whole number', 'threshold must be a decimal number']

科學計算

typescript
import { isFloat } from 'radash'

function calculateStandardDeviation(values: unknown[]): number {
  const validFloats = values.filter(isFloat)
  
  if (validFloats.length < 2) {
    return 0
  }
  
  const mean = validFloats.reduce((sum, val) => sum + val, 0) / validFloats.length
  const squaredDifferences = validFloats.map(val => Math.pow(val - mean, 2))
  const variance = squaredDifferences.reduce((sum, val) => sum + val, 0) / validFloats.length
  
  return Math.sqrt(variance)
}

const measurements = [1.5, 2.3, 3.1, 4.7, 5.2, 'invalid', 6.1, null, 7.3]

console.log(calculateStandardDeviation(measurements)) // 2.05

游戲開發

typescript
import { isFloat } from 'radash'

interface PlayerStats {
  health: unknown
  mana: unknown
  experience: unknown
  level: unknown
}

function validatePlayerStats(stats: PlayerStats) {
  const validStats: Partial<PlayerStats> = {}
  
  if (isFloat(stats.health)) {
    validStats.health = stats.health
  }
  
  if (isFloat(stats.mana)) {
    validStats.mana = stats.mana
  }
  
  if (isFloat(stats.experience)) {
    validStats.experience = stats.experience
  }
  
  if (typeof stats.level === 'number' && Number.isInteger(stats.level)) {
    validStats.level = stats.level
  }
  
  return validStats
}

const playerStats: PlayerStats = {
  health: 100.0,
  mana: 50.5,
  experience: 1250.75,
  level: 10
}

console.log(validatePlayerStats(playerStats))
// { health: 100.0, mana: 50.5, experience: 1250.75, level: 10 }

金融計算

typescript
import { isFloat } from 'radash'

interface FinancialData {
  principal: unknown
  rate: unknown
  time: unknown
  amount: unknown
}

function calculateInterest(data: FinancialData): number {
  if (!isFloat(data.principal) || !isFloat(data.rate) || !isFloat(data.time)) {
    return 0
  }
  
  return data.principal * data.rate * data.time
}

function validateFinancialData(data: FinancialData) {
  const errors: string[] = []
  
  if (!isFloat(data.principal)) {
    errors.push('Principal must be a decimal number')
  }
  
  if (!isFloat(data.rate)) {
    errors.push('Rate must be a decimal number')
  }
  
  if (!isFloat(data.time)) {
    errors.push('Time must be a decimal number')
  }
  
  if (!isFloat(data.amount)) {
    errors.push('Amount must be a decimal number')
  }
  
  return errors
}

const loanData: FinancialData = {
  principal: 10000.0,
  rate: 0.05,
  time: 2.5,
  amount: 11250.0
}

console.log(calculateInterest(loanData)) // 1250
console.log(validateFinancialData(loanData)) // []

注意事項

  1. 整數檢查: 整數不被認為是浮點數
  2. NaN檢查: NaN不被認為是浮點數
  3. 無窮大: Infinity和-Infinity不被認為是浮點數
  4. 類型守衛: 作為TypeScript類型守衛使用
  5. 性能: 檢查速度很快,適合高頻使用

與其他方法的區別

  • isFloat(): 檢查是否為浮點數
  • isNumber(): 檢查是否為數字(包括整數)
  • Number.isInteger(): 檢查是否為整數
  • typeof value === 'number': 檢查是否為數字類型

實際應用場景

  1. 表單驗證: 驗證用戶輸入的浮點數
  2. API處理: 處理API響應中的浮點數字段
  3. 數據庫操作: 驗證數據庫字段類型
  4. 數學計算: 確保計算參數為浮點數
  5. 金融應用: 處理貨幣和利率計算
  6. 科學計算: 處理測量和統計數據

Released under the MIT License.