[英]How to use Template Literal Types as a return type property in TypeScript
我正在尝试TypeScript 4.1版本中的新模板文字类型功能,并希望创建 function 接受字符串文字参数,然后使用该参数声明返回类型 ZA8CFDE6331BD59EB26AC96B 的属性。
作为一个实验,我试图围绕 React 的useState
function 创建一个小包装器,但无法让它工作。
这是我尝试过的:
function useNamedState<TValue>(name: string, initialValue: TValue): {
[typeof name]: TValue;
[`set${Capitalize<typeof name>}`]: (newValue: TValue) => void;
} {
const [value, setValue] = useState(initialValue);
return {
[name]: value,
[`set${capitalize(name)}`]: newValue => setValue(newValue),
};
}
我不确定这里应该使用什么正确的语法。 我想实现如下API:
const {apples, setApples} = useNamedState<number|null>('apples', null);
我怎样才能让它工作?
您需要一个额外的类型来捕获name
参数的实际字符串文字类型。 您还需要使用映射类型或预定义的Record
映射类型来创建具有来自字符串文字类型的键的类型。
一个复杂的问题是 TS 不支持部分参数推断,因此对于如何定义 function,您有几个选择。
function useNamedState<TValue, TName extends string>(name: TName, initialValue: TValue): Record<TName, TValue> & Record<`set${Capitalize<typeof name>}`, (newValue: TValue) => void>
{ /*...*/ }
const {apples, setApples} = useNamedState<number|null, 'apples'>('apples', null); // explicit args
const {bannana, setBannana} = useNamedState('bannana', null as null | number); // implicit args,but with type assertion on value
function useNamedState <TName extends string>(name: TName)
{
return function <TValue>(initialValue: TValue): Record<TName, TValue> & Record<`set${Capitalize<typeof name>}`, (newValue: TValue) => void> {
// ....
}
}
// TValue specified in the middle is hard to read
const {apples, setApples} = useNamedState('apples')<number|null>(null);
function useNamedState <TValue>(initialValue: TValue)
{
return function <TName extends string>(name: TName): Record<TName, TValue> & Record<`set${Capitalize<typeof name>}`, (newValue: TValue) => void> {
//....
}
}
const {apples, setApples} = useNamedState<number|null>(null)('apples');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.