[Typescript] ts-toolbelt F.Narrow preserve the exactly data for function arguement
Example code:
interface Fruit {
name: string;
price: number;
}
export const wrapFruit = <TFruits extends Fruit[]>(fruits: TFruits) => {
const getFruit = (name: unknown): unknown => {
return fruits.find((fruit) => fruit.name === name);
};
return {
getFruit,
};
};
const fruits = wrapFruit([
{
name: 'apple',
price: 1,
},
{
name: 'banana',
price: 2,
},
]);
The wrapFruit
function has following types:
We saw that <{name: string, price: nunmber}>
which is not what we want.
We want:
To do that we need to use the F.Narrow
type helper from 'ts-toolbelt'
export const wrapFruit = <TFruits extends Fruit[]>(fruits: F.Narrow<TFruits>) => {
const getFruit = (name: unknown): unknown => {
return fruits.find((fruit) => fruit.name === name);
};
return {
getFruit,
};
};
Narrow:
export declare type Try<A1 extends any, A2 extends any, Catch = never> = A1 extends A2 ? A1 : Catch;
export declare type Narrowable = string | number | bigint | boolean;
export declare type NarrowRaw<A> = (A extends [] ? [] : never) | (A extends Narrowable ? A : never) | ({
[K in keyof A]: A[K] extends Function ? A[K] : NarrowRaw<A[K]>;
});
declare type Narrow<A extends any> = Try<A, [], NarrowRaw<A>>;
function fn<T>(inputs: T) {}
fn([{name: 'apple', price: 1}])
With Typescript V5.0, there will be a <const T> https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#const-type-parameters
Which doing pretty much the same thing as F.Narrow.
Another appraoch
interface Fruit {
name: string;
price: number;
}
export const wrapFruit = <const T extends Fruit>(fruits: T[]) => {
const getFruit = <TName extends T['name']>(name: TName) => {
return fruits.find((fruit) => fruit.name === name) as Extract<T, {name: TName}>;
};
return {
getFruit,
};
};
const fruits = wrapFruit([
{
name: "apple",
price: 1,
},
{
name: "banana",
price: 2,
},
]);
const banana = fruits.getFruit("banana");
const apple = fruits.getFruit("apple");
// @ts-expect-error
const notAllowed = fruits.getFruit("not-allowed");
type tests = [
Expect<Equal<typeof apple, { readonly name: "apple"; readonly price: 1 }>>,
Expect<Equal<typeof banana, { readonly name: "banana"; readonly price: 2 }>>
];
分类:
TypeScript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-05-03 [AWS DA Guru] Monitoring
2021-05-03 [AWS] Lab: Install CloudWatch Agent on EC2 instance
2020-05-03 [React Testing] Test a Custom React Hook with React’s Act Utility and a Test Component
2020-05-03 [React Testing] Test react-router-dom Router Provider with createMemoryHistory
2018-05-03 [React Native] Target both iPhone and iPad with React Native
2018-05-03 [Angular] Increasing Performance by using Pipe
2018-05-03 [Angular] Angular CDK Intro