从通用函数获取参数类型

时间:2020-06-24 18:01:17

标签: typescript

请注意,这与How to get argument types from function in TypescriptIs there ArgumentsType like ReturnType in Typescript?有关,它们的答案可能适用于我要执行的操作,但它们不能满足我的确切需求,因为它们没有涵盖通用功能。

我有一个3rd party库,它没有导出我想使用的类型。但是,它确实导出了一个函数,该函数具有我要使用的类型的参数。我想得到一个类型,即使它没有被导出。

我认为可行的方法是使用Parameters<T>实用程序类型来偷​​偷发现该类型。但是,我不确定如何在保留原始类型的通用性的同时做到这一点。

明确地说,我正在尝试利用StyleSheet.NamedStyles<T>中的类型。它不会导出,但是以该类型作为参数的StyleSheet.create函数是。

我认为可以遵循以下方法,但是T变成any

import {StyleSheet} from "react-native";

type MyNamedStyles<T> = Parameters<typeof StyleSheet.create>[0];

我也可以只在本地重新创建类型,但这会增加我需要导入的内容,而我并没有直接依赖它们,只是create函数。


我的特定用例是用于React Native,但我还有以下示例来说明其要点:

// Pretend 3rd party lib
declare namespace Foo {
    type Thing<T> = {[P in keyof T]: string}; // Not exported
    export type FakeThing<T> = Thing<T>; // Pretend that this doesn't exist
    export function doStuff<T extends Thing<T>>(stuff: T): T; // Is exported

    type OtherThing = {k: string};
    export function doMoreStuff(stuff: OtherThing): OtherThing;
}

/*
 * What I really want, is StuffArgs to be created but
 * with the genericism retained which gives me a roundabout
 * way of actually getting Thing<T>.  Right now I can only
 * really get Thing<any>.
 */
type StuffFirstArg<T> = Parameters<typeof Foo.doStuff>[0];

/*
 * If doStuff weren't generic, the following would get me
 * what I want even though OtherThing isn't exported.
 */
type MoreStuffArg = Parameters<typeof Foo.doMoreStuff>[0];

// Using just doStuff
interface IPerson {
    name: string;
    age: number;
}

const bob: Foo.FakeThing<IPerson> = {
    name: "Bob Barker",
    age: "Old"
};

Foo.doStuff(bob);

// Using StuffArgs
interface IPlace {
    name: string;
    visitors: number;
}

// Am able to create
const biggestBallOfYarn: StuffFirstArg<IPlace> = {
    name: "Biggest Ball of Yarn",
    //visitors: 12, // Good! Type 'number' is not assignable to type 'string'
    reviews: "Not good" // Bad! Should have told me "reviews" isn't part of IPlace
};

const stuffedBallOfYarn = Foo.doStuff(biggestBallOfYarn); // Foo.Thing<any>

0 个答案:

没有答案