typescript对象里中括号引用应该怎么写才正确?

新手上路,请多包涵
const Tween = {
    Linear: (t: number, b: number, c: number, d: number) => (c * t) / d + b,
    Quad: {
        easeIn: (t: number, b: number, c: number, d: number) => c * (t /= d) * t + b,
        easeOut: (t: number, b: number, c: number, d: number) => -c * (t /= d) * (t - 2) + b,
        easeInOut: (t: number, b: number, c: number, d: number) => ((t /= d / 2) < 1 ? (c / 2) * t * t + b : (-c / 2) * (--t * (t - 2) - 1) + b),
    }
}

type TweenFunc =
    | 'Linear'
    | 'Quad.easeIn'
    | 'Quad.easeOut'
    | 'Quad.easeInOut';
    
export default (tween: TweenFunc) => {
    const [name, func] = tween.split('.');
    if (!func) return Tween.Linear;
    // Tween[name]这里会报错
    // element implicitly has an any type because expression of type string cant be used to index
    return Tween[name][func];
};

谢过各位大佬

阅读 4.1k
3 个回答

TypeScript 目前还不支持字面量类型拆分组合,你可以

  1. Tween 扁平化,不搞多层。
  2. 强制转换 split 出来的类型,这需要你同时手动维护两个 type。
  3. 或者 tween 用 string 类型,对 split 出来的结果做额外判断,确保 Tween 中有对应的域。

按 2 的例子:

 const Tween = {
     Linear: (t: number, b: number, c: number, d: number) => (c * t) / d + b,
     Quad: {
         easeIn: (t: number, b: number, c: number, d: number) => c * (t /= d) * t + b,
         easeOut: (t: number, b: number, c: number, d: number) => -c * (t /= d) * (t - 2) + b,
         easeInOut: (t: number, b: number, c: number, d: number) => ((t /= d / 2) < 1 ? (c / 2) * t * t + b : (-c / 2) * (--t * (t - 2) - 1) + b),
     }
 }
 
 type TweenFunc =
     | 'Linear'
     | 'Quad.easeIn'
     | 'Quad.easeOut'
     | 'Quad.easeInOut';
 
+type TweenNameFuncPair =
+    | ['Linear']
+    | ['Quad', 'easeIn']
+    | ['Quad', 'easeOut']
+    | ['Quad', 'easeInOut']
     
 export default (tween: TweenFunc) => {
+    const pair = tween.split('.') as TweenNameFuncPair;
+    if (!pair[1]) return Tween.Linear;
+    return Tween[pair[0]][pair[1]];
 };
 
const Tween: Record<string, any> = {
    Linear: (t: number, b: number, c: number, d: number) => (c * t) / d + b,
    Quad: {
        easeIn: (t: number, b: number, c: number, d: number) => c * (t /= d) * t + b,
        easeOut: (t: number, b: number, c: number, d: number) => -c * (t /= d) * (t - 2) + b,
        easeInOut: (t: number, b: number, c: number, d: number) => ((t /= d / 2) < 1 ? (c / 2) * t * t + b : (-c / 2) * (--t * (t - 2) - 1) + b),
    }
}

type TweenFunc =
    | 'Linear'
    | 'Quad.easeIn'
    | 'Quad.easeOut'
    | 'Quad.easeInOut';

const test = function(tween: TweenFunc) {
    const [name, func] = tween.split('.');
    if (!func) return Tween.Linear;
    // Tween[name]这里会报错
    // element implicitly has an any type because expression of type string cant be used to index
    return Tween[name][func];
};

//@ts-ignore

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进