询问两个ts问题

更新问题

// 问题一主要解决 Arr引入太冗余了。如果我能直接获取zfc的长度,就不用引入Arr
type getStr<Str extends string, len extends number, Arr extends string[] = [], result extends string = ''> = 
Str extends `${infer pre}${infer next}` ? Arr['length'] extends len ? result : getStr<next, len, [...Arr, pre], `${result}${pre}`> : never

// 这里c 返回的abc 而不是 string。有更好的效果
type c = getStr<'abcd', 3>  

//问题二 主要是解决用户传入参数到方法中 返回用户正确的值, 能增加代码的可读性

感谢 各位大佬了

// 问题一 如何让b 返回a的长度,而不是number
type a = '1234'
type b  = a["length"]




//问题二 下面这个方法如何用ts定义限定b是a里面的key, 然后返回正确的结构
function  getValue(a: object, b: string[]) {
  return b.reduce((pre,next) => {
    return pre[next]
  }, a)
}
//getValue({a: {b: {c: 1}}}, ['a', 'b', 'c']) => 1
阅读 2.1k
2 个回答

说实在的没太看明白你的需求。

但是,我们写程序的目的就是为了处理复杂的逻辑。写类型的逻辑是为了尽量识别出来逻辑中可能存在的错误。

换句话说,处理问题分两步,先粗后细就是

  • 用编译器或工具,静态分析代码,找出潜在的问题。这一步加上类型约束可以更容易检查出来潜在的问题。
  • 在运行时通过动态的处理逻辑。其中容错处理部分是更精细的找到问题并处理掉。

说实在的,我不太赞同 TypeScript 把值作为类型在处理。但是为了兼容 JavaScript 对象属性的灵活性,TS 不得不提供这样的能力。但我们写程序的时候,应该尽可能的让逻辑去处理逻辑,让类型去做粗放的约束。要不然,就不是增强阅读性而是降低阅读性了。所以这里可以简单的做一下分工:编译器(TS Compiler)处理类型计算,运行时(JS Runtime)还可以处理值计算。

对于获取字符串长度这个事情,是个取值的过程,本来就应该是运行逻辑干的事情(只有运行时才可能计算出来字符串长度)。编译逻辑只能判断,这是字符串类型(亦或其子类型),还是其他类型。

不要希望什么事情都交给 TypeScript 去处理。如果有一天 TypeScript 能把运行逻辑都处理了,那 TSC 就是 TypeScript Runtime Engine,而 TypeScript 也就真的是 Type Script,与 JavaScript 没啥关系了。


顺便说一下 getValue

function getValue(a: unknown, keys: string[]): unknown {
    return keys.reduce((acc, key) => {
        return acc[key];
    }, a as any);
}

const r = getValue({ a: { b: { c: 1 } } }, ["a", "b", "c"]);
console.log(r);  // 1

对于输入对象来说,你不可知道能运行每一步拿到的是什么属性,也不不可能知道拿到的是什么类型的值。比如说 { a: 1, b: "a", c: true } 这样一个对象,第一步取了属性之后,只可能知道拿到的是 number | string | boolean,但具体是哪一个,只有运行时知道。reduce 过程中第一层就拿到了复合类型,后面的就更加复杂了,只可能声明为 unknown 或者 any,由代码在运行时动态进行检查和处理。

image.png

完全没看到你所说的可读性,而且还丧失了代码的弹性。
问题1: const from = 'abcd'; const str = from.substr(0, 3); 简单明确的一行代码,为什么要搞成那么多行?
问题2: function getObjectValueByPath<T = any>(obj: {[key: string]: any}, path: string): T | undefined 表示根据传入的路径查找对象属性的值,找到则返回,找不到返回undefined。同样简明清晰。

我们说明一个东西是什么,建议 怎么用就好了,还非要开发人员必须怎么用,这累不累?再说了,编译运行都避免不了bug问题,你寄希望于严格的ts声明就把bug扼杀在摇篮里,是不是期望过高了?

对于问题二再说一句,你的意思开发人员很清楚obj的结构,然后确定的自己写入的路径正确,既然这样,直接调用obj.a.b.c就行了,还写什么方法?不就是因为不确定obj的结构,尝试着去取值你才定义这个方法吗?

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