如何通过全局d.ts实现localStorage的TypeScript类型安全调用?
实现localStorage的类型安全key校验(全局d.ts方案)
原方案问题分析
你之前的全局d.ts扩展方式无法生效,原因是TypeScript的接口合并规则:新定义的方法重载会添加到原有Storage接口中,而非替换。原lib.dom.d.ts中getItem的参数类型是string,合并后getItem同时支持string和'abc'两种key,因此传入'xyz'(属于string)不会触发类型错误。
正确解决方案
以下两种方案均无需包装器,仅通过全局d.ts实现严格的key校验:
方案一:条件类型限制(推荐)
利用条件类型,仅允许指定key通过校验,其他key会被推断为never从而触发错误:
// global.d.ts declare global { interface Storage { getItem<K extends string>(key: K extends 'abc' ? K : never): string | null; setItem<K extends string>(key: K extends 'abc' ? K : never, value: string): void; // 如需限制removeItem,可添加以下代码 removeItem<K extends string>(key: K extends 'abc' ? K : never): void; } } export {}; // 标记为模块,确保全局声明生效
验证:调用localStorage.getItem('xyz')时,TypeScript会提示类型'"xyz"'的参数不能赋给类型'never'的参数,达到预期校验效果。
方案二:完全重写Storage接口
若需彻底替换原有Storage的方法类型,可重新定义整个接口(需保留所有原有方法,避免类型丢失):
// global.d.ts declare global { interface Storage { getItem(key: 'abc'): string | null; setItem(key: 'abc', value: string): void; removeItem(key: 'abc'): void; clear(): void; key(index: number): string | null; readonly length: number; } } export {};
此方案直接限定getItem/setItem/removeItem的key只能是'abc',其他方法保持原有类型不变。
内容的提问来源于stack exchange,提问作者coure2011
相关产品推荐
相关产品推荐

