TypeScript 字符串十二题例【实践篇】

古早课件,未必完备。姑且写之,姑且看之。

TypeScript 字符串十二题例【进阶篇】继续讨论:

题十一:得到对象中的值访问字符串

题干

完成 createI18n 函数中的 ObjectAccessPaths,限制函数i18n的参数为合法的属性访问字符串

function createI18n<Schema>(schema: Schema): 
((path: ObjectAccessPaths<Schema>) => string) {
	return [{schema}] as any
}

要求得到i18n函数的参数类型为:
home.topBar.title | home.topBar.welcome | home.bottomBar.notes | login.username | login.password

const i18n = createI18n({
	home: {
		topBar: {
			title: 'LinuxDo',
			welcome: '欢迎加入'
		},
		bottomBar: {
			notes: '真诚、友善、团结、专业'
		}
	},
	login: {
		username: '用户名',
		password: '密码'
	}
})

i18n('home.topBar.title')           // correct
i18n('home.topBar.welcome')         // correct
i18n('home.bottomBar.notes')        // correct

i18n('home.login.abc')              // error,不存在的属性
i18n('home.topBar')                 // error,没有到最后一个属性

题解

type RemoveFirstDot<T> = T extends `.${infer L}` ? L : T

type ObjectAccessPaths<T, P extends string = '', K = keyof T> = 
  K extends keyof T ? 
    (K extends string ? 
      (T[K] extends Record<string, any> ?
		ObjectAccessPaths<T[K], `${P}.${K}`> : RemoveFirstDot<`${P}.${K}`>
		) : never
	) : never

解析

  1. 通过遍历对象的key得到联合类型
  2. T: 传入的路径对象 P: 拼接的字符串 K: 对象的key
  3. K 肯定是对象的key,这里的never没用,这一步主要是为了获得对象key的分布情况
  4. 遍历一次后判断对象的值T[K]是否依旧是对象
  5. 如果T[K]是对象,那就继续遍历,只是此时的第一个参数T变为T[K],第二个参数P则是拼接的字符串 ${P}.${K}
  6. 如果不是对象,就返回拼接好的字符串${P}.${K}即可

注意:由于P的初始值为空字符串,所以最终拼接的字符串开头也有连接符(.),所以最终借助RemoveFirstDot去掉

整体思路还是不停的去遍历检查,要学会灵活运用与变通

题十二:定义组件的监听事件类型

题干

实现 ComponentEmitsType<Emits> 类型,将

type Source = {
	'handle-open': (flag: boolean) => true,
	'preview-item': (data: {item: any, index: number}) => true,
	'close-item': (data: {item: any, index: number}) => true,
}

转化为类型 type Target = ComponentEmitsType<Source>

type Target = {
    onHandleOpen?: (flag: boolean) => void,
    onPreviewItem?: (data: { item: any, index: number }) => void,
    onCloseItem?: (data: { item: any, index: number }) => void,
}

题解

略。


9 个赞

大鹅高产:tieba_087:

2 个赞

可爱的老板在催我,晚点再补 :tieba_087:

2 个赞

虽然我看不懂
但是感觉好高大上

鹅佬继续,我给你加油:tieba_087:

1 个赞

你可以看懂 :tieba_087:

我就看懂了这么多汉字:tieba_087:

1 个赞

鹅鹅鹅真牛

1 个赞

太强了,大鹅

1 个赞

感谢大鹅分享

1 个赞

支持大鹅老师 :bili_110:

1 个赞

最后一题做不出来,弹你:lark_107::lark_107:

1 个赞

大鹅嘛时候开下一节课啊 :tieba_025:

2 个赞

大伙不爱看 :tieba_087: 骗不到赞

1 个赞

也许是太硬核了 :tieba_087:

2 个赞

没有含金量 :tieba_087: 我还是适合水 :sweat_drops: :sweat_drops: :sweat_drops:

1 个赞

Css!!css!

1 个赞

怎么会呢,只能说明会ts的人数太多了没有点进来 :tieba_025: