Typescript 定义方法&x27;使用keyof时的返回类型
在访问对象的属性之前,想要创建一个包含一些对象的类,并执行空/未定义的检查。 当然,应该键入结果(可能Typescript 定义方法&x27;使用keyof时的返回类型,typescript,maybe,Typescript,Maybe,在访问对象的属性之前,想要创建一个包含一些对象的类,并执行空/未定义的检查。 当然,应该键入结果(可能或) 以下是一个例子: class Maybe < T > { constructor(public value: T) {} static of < P > (obj: P): Maybe < P > { return new Maybe(obj); } map < TResult > (fn: (arg: T) =&g
class Maybe < T > {
constructor(public value: T) {}
static of < P > (obj: P): Maybe < P > {
return new Maybe(obj);
}
map < TResult > (fn: (arg: T) => TResult): Maybe < TResult > {
return this.isNothing ? nothing : new Maybe(fn(this.value));
}
public get < P extends keyof T > (name: P): Maybe < T[P] > {
return this.isNothing ? nothing : Maybe.of(this.value[name]);
}
get isNothing(): boolean {
return this.value == null;
}
}
let nothing = new Maybe(null);
但在定义“apply”函数时遇到问题,该函数将接受对象属性的名称,实际上是一个函数,执行该函数并返回 // T[fName]: (...args)=> TResult
public apply < P extends keyof T > (fnName: P, ...args: any[]) /*: Maybe<Tresult> */ {
if (!this.isNothing) {
let res = null;
let fn = this.value[fnName];
if (isF(fn)) {
return Maybe.of(fn(...args));
}
}
return nothing;
}
//T[fName]:(…args)=>TResult
public apply(fnName:P,…args:any[])/*:Maybe*/{
如果(!this.isNothing){
设res=null;
设fn=this.value[fnName];
如果(isF(fn)){
(fn(…args))的返回值;
}
}
一无所获;
}
找不到定义“应用”调用结果的解决方案
让fResult=Maybe.of(t).apply('f','foo');
//弗雷索也许是
谢谢首先,让我把课放到一边,一步一步地介绍一些基本操作
可以使用泛型函数检查对象是否为null,然后返回该对象的某些属性。可以从属性的类型推断函数的返回类型:
function maybeGet<T, N extends keyof T>(t: T | undefined, n: N) {
return t ? t[n] : undefined;
}
你可以这样使用它
const a = maybeGet(t, 'a');
实际上,a
的类型被推断为{id:number;name:string;}
然后,您可以定义泛型类型别名来描述返回类型为R
的函数:
type FR<R> = (...args: any[]) => R;
问题是如何将这两种操作组合在一个通用操作中
使用映射类型,您可以尝试为具有返回R
作为属性的函数的对象定义类型别名
type FM<N extends string, R> = {[n in N]: FR<R>};
但是,它不适用于您的测试,因为TypeScript出于某种原因将使用keyof T
作为N
,并坚持要求test
中的所有属性都必须可调用:
const tm = maybeApplyMemberFunction(t, 'f');
// Argument of type 'Test' is not assignable to parameter of type
// 'FM<"a" | "f", Test>'.
// Types of property 'a' are incompatible.
// Type '{ id: number; name: string; }' is not assignable to type 'FR<Test>'.
// Type '{ id: number; name: string; }' provides no match for the signature
// '(...args: any[]): Test'.
不幸的是,typescript无法指定N
应该是N
参数的确切文本类型。我不清楚您的问题是什么。在您的代码中,您只是忘记声明类型参数Tresult
。没关系,我误读了,我明白了问题所在。我想这个问题可以浓缩一点,你想要什么还不清楚。似乎您只是在问如何在使用keyof
时获取方法的返回类型。如果没有检测并确保“f”确实是函数名的方法(以某种方式表示P extends-keyof-T,TR,T[P]extends(…args:any[])=>TR我不确定这是否可行。
type FR<R> = (...args: any[]) => R;
function maybeApplyFunction<R>(f: FR<R> | undefined, ...args: any[]) {
return f ? f(...args) : undefined;
}
const r = maybeApplyFunction(t.f, 'foo'); // r has type 'Test'
const tf = maybeApplyFunction(maybeGet(t, 'f'), 'foo');
// tf has type `Test`
type FM<N extends string, R> = {[n in N]: FR<R>};
function maybeApplyMemberFunction<N extends string, R>(o: FM<N, R>, n: N, ...args: any[]) {
return o ? o[n](...args) : undefined;
}
class T1 { f() { return new T1() } };
const b = maybeApplyMemberFunction(new T1(), 'f');
// b has type T1
const tm = maybeApplyMemberFunction(t, 'f');
// Argument of type 'Test' is not assignable to parameter of type
// 'FM<"a" | "f", Test>'.
// Types of property 'a' are incompatible.
// Type '{ id: number; name: string; }' is not assignable to type 'FR<Test>'.
// Type '{ id: number; name: string; }' provides no match for the signature
// '(...args: any[]): Test'.
function maybeApplyMemberFunctionF<N extends 'f', R>(o: FM<N, R>, n: N, ...args: any[]) {
return o ? o[n](args) : undefined;
}
const t1 = maybeApplyMemberFunctionF(t, 'f');