typescript - 如何在 TypeScript 中使用泛型索引记录?
问题描述
我有一个LocalizationMap
并且我正在尝试使用泛型对其进行索引,下面是我的尝试,我在出现类型错误的地方添加了注释
interface Greeting {
type: string;
props: never;
}
interface NumbersSeven {
type: number;
props: never;
}
interface ExtrasArraysMixed {
type: [string, number];
props: ExtrasArraysMixedProps;
}
interface ExtrasArraysMixedProps {
name: string;
}
interface City {
type: string;
props: CityProps;
}
interface CityProps {
city: string;
}
interface LocalizationMap {
greeting: Greeting;
"numbers.seven": NumbersSeven;
"extras.arrays.mixed": ExtrasArraysMixed;
city: City;
}
const availableLanguages = ["en", "nl"] as const;
type Cache = Record<typeof availableLanguages[number], LocalizationMap>;
export const setLanguage = <T extends keyof Cache>(lang: T) => {
// Type '"props"' cannot be used to index type 'K'.
return <K extends keyof Cache[T], V = K["props"]>(
key: K,
...placeholders: V extends never ? [] : [V]
): V => {
let translation = key
// Property 'split' does not exist on type 'K'.
.split(".")
.reduce((acc, val) => acc[val], cache[lang]);
return translation;
};
};
// Usage I am trying to get
const x = setLanguage("en");
// An argument for 'placeholders' was not provided.
x("greeting");
x("extras.arrays.mixed", { name: "Dan" });
解决方案
看来您正在索引错误的类型,并且可能想要这样的东西:
const availableLanguages = ["en", "nl"] as const;
type CacheKeys = typeof availableLanguages[number]
type Cache = Record<CacheKeys, LocalizationMap>;
export const setLanguage = <T extends CacheKeys>(lang: T) => {
return <K extends keyof LocalizationMap, V extends LocalizationMap[K]['props']>
(
key: K,
...placeholders: V[]
): V => {
return key.split(".").reduce((acc, val) => acc[val], cache[lang]);
};
};
const x = setLanguage("en");
x("greeting"); // works
x("extras.arrays.mixed", { name: "Dan" }); // works
x("city", { city: "Odessa" }); // works
推荐阅读
- c# - 在 WPF 应用程序中使用 MVVMLight ViewModelLocator 时如何在 MainViewModel 之前加载 DataService?
- powershell - 引用全局变量时是否可以选择使用 $global: 范围前缀?
- xslt - 使用 document() 时排除 XSLT 中的单个元素
- go - 有没有办法将二维切片插入 sqlite 数据库?
- smartsheet-api - 在 API 调用中创建系统列空白
- javascript - 如何检查url是否包含父页面url?
- angular - Ionic 3 按钮控制器
- python - 尽管使用推荐的方法来阻止它,pyinstaller 仍然打开控制台
- php - 如何使用 ajax 在引导模式中加载某种类型的文件
- java - 匿名类可以换成lambda吗?