打字稿/类型安全柯里化函数 [英] Typescript / Type Safe Curried Functions

查看:30
本文介绍了打字稿/类型安全柯里化函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在打字稿中安全地键入柯里化函数?特别关于下面的例子

How to safely type curried functions in typescript? With particular regard to the following example

interface Prop {
    <T, K extends keyof T>(name: K, object: T): T[K];
    <K>(name: K): <T>(object: T) => /* ?? */;
}

const prop: Prop = (key, object) => object[key];

const valid1 = prop('foo', { foo: 'hello' }); // string
const valid = prop('foo')({ foo: 'hello' });  // string

// `never`, since `baz` does not exist in { foo: string }
const invalid = prop('baz')({ foo: 'hello' }); // never

推荐答案

function超载

function prop<T, K extends keyof T>(name: K, obj: T): T[K]
function prop<K extends PropertyKey>(name: K):
    <T extends Record<K, unknown>>(obj: T) => T[K]
function prop(name: any, obj?: any) { 
    if (obj === undefined) {
        return (obj: any) => obj[name]
    } else {
        return obj[name]
    }
}
// weak types used in impl for simplicity, as they don't matter for the caller.
// also this function body is not really complex

const valid1 = prop('foo', { foo: 'hello1' }); // string
const valid2 = prop('foo')({ foo: 'hello2' });  // string
const invalid = prop('baz')({ foo: 'hello' }); // compile error, `baz` not in { foo: string } 

示例

interface Prop {
    <T, K extends keyof T>(name: K, obj: T): T[K];
    <K extends PropertyKey>(name: K): <T extends Record<K, unknown>>(obj: T) => T[K]
}

const prop: Prop = (name: any, obj?: any) => {
    if (obj === undefined) {
        return (obj: any) => obj[name]
    } else {
        return obj[name]
    }
}
// weak types used here for simplicity like in first solution

const valid1 = prop('foo', { foo: 'hello1' }); // string
const valid2 = prop('foo')({ foo: 'hello2' });  // string
const invalid = prop('baz')({ foo: 'hello' }); // never
console.log(valid1, valid2) // hello1 hello2

示例

注意:函数重载和函数类型不能完全互换使用(更多信息此处此处).对于后者,可能需要在函数实现部分用 any 注释类型,以解决定义的调用签名中不兼容的返回类型 - 请查看此 游乐场一个例子

Note: Function overloads and function types cannot be used completely interchangeably (more infos here or here). With latter, it may be necessary to annotate types with any in the function implementation part to account for incompatible return types in the defined call signatures - checkout this playground for an example.

这篇关于打字稿/类型安全柯里化函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆