首页 > 解决方案 > TypeScript 媒体查询

问题描述

我正在尝试将我原来的“.js”媒体查询转换为“.ts”。我原来的实用程序很容易转换:

const min = (width: number) => `only screen and (min-width: ${width}em)`
const max = (width: number) => `only screen and (max-width: ${width}em)`

// The screen widths in em units.
export const screens = {
  phone: 30,
  phablet: 40,
  tablet: 50,
  netbook: 60,
  laptop: 70,
  desktop: 100,
}

export const mediaQueries = Object.entries( screens )
  .reduce<Record<string, string | number>>(
    ( acc, [key, val] ) => {
      const Key = key[0].toUpperCase() + key.substr( 1 )
      // css query
      acc[`min` + Key] = `@media ` + min( val )
      acc[`max` + Key] = `@media ` + max( val )
      // js query (see window.matchMedia)
      acc[`min` + Key + `Js`] = min( val )
      acc[`max` + Key + `Js`] = max( val )
      return acc
    }, {}
  )

React 钩子难以访问媒体查询。这是我得到的错误:

'string | 类型的参数 number' 不可分配给“string”类型的参数。类型“数字”不可分配给类型“字符串”.ts(2345)

import { useEffect, useState } from 'react'
import { mediaQueries } from '../utils/mediaQueries'

interface myCallbackType { (myArgument: string): void }

export const useMediaQuery = ( query: string, cb: myCallbackType ) => {
  const [matches, setMatches] = useState( false )

  useEffect( () => {
    const qry = window.matchMedia( query )
    setMatches( qry.matches )
    const handleMatch = ( q: any) => {
      setMatches( q.matches )
      if ( cb instanceof Function ) cb( q.matches )
    }

    qry.addListener( handleMatch )
    return () => qry.removeListener( handleMatch )
  }, [query, cb] )

  return matches
}

const validKeys = Object.keys( mediaQueries ).filter(
  key => !key.includes( `Js` )
)

export const useScreenQuery = ( key: string, cb: myCallbackType ) => {
  if ( !mediaQueries[key + `Js`] )
    throw new TypeError(
      `useScreenQuery received an invalid key: ${key}.`
      + ` Should be one of ${validKeys}`
    )
  return useMediaQuery( 
    mediaQueries[key + `Js`], // <- Error here
    cb 
  )
}

使用 TypeScript 处理这个钩子的正确方法是什么?

标签: reactjstypescript

解决方案


推荐阅读