xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

TypeScript LeetCode 面试题 All In One

TypeScript LeetCode 面试题 All In One

TypeScript In Action

TypeScript 复杂类型

编写复杂的 TypeScript 类型

// 方法「只可能」有两种类型签名

interface Action<T> {
  payload?: T
  type: string
}

asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>>

syncMethod<T, U>(action: Action<T>): Action<U>

interface Action<T> {
  payload?: T;
  type: string;
}

// 还可能有一些任意的「非函数属性」

class EffectModule {
  count = 1;
  message = "hello!";

  delay(input: Promise<number>) {
    return input.then((i) => ({
      payload: `hello ${i}!`,
      type: "delay",
    }));
  }

  setMessage(action: Action<Date>) {
    return {
      payload: action.payload!.getMilliseconds(),
      type: "set-message",
    };
  }
}

// 现在有一个叫 connect 的函数,它接受 EffectModule 实例,将它变成另一个对象,
// 这个对象上只有「EffectModule 的同名方法」,但是方法的类型签名被改变了

asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>> 
// 变成了
asyncMethod<T, U>(input: T): Action<U>

syncMethod<T, U>(action: Action<T>): Action<U> 
// 变成了
syncMethod<T, U>(action: T): Action<U>

demo

interface Action<T> {
  payload?: T;
  type: string;
}

class EffectModule {
  count = 1;
  message = "hello!";

  delay(input: Promise<number>) {
    return input.then((i) => ({
      payload: `hello ${i}!`,
      type: "delay",
    }));
  }

  setMessage(action: Action<Date>) {
    return {
      payload: action.payload!.getMilliseconds(),
      type: "set-message",
    };
  }
}


type Connected = {
  delay(input: number): Action<string>;
  setMessage(action: Date): Action<number>;
};

const effectModule = new EffectModule();
const connected: Connected = connect(effectModule);

要求:

在题目链接[1] 里面的 index.ts 文件中,
有一个 type Connect = (module: EffectModule) => any,将 any 替换成题目的解答,让编译能够顺利通过,
并且 index.ts 中 connected 的类型与 Connected「完全匹配」

type Connected = {
  delay(input: number): Action<string>;
  setMessage(action: Date): Action<number>;
};

https://github.com/LeetCode-OpenSource/hire/blob/master/foundations-zh/src/index.ts


export interface ErrorMessage {
  message: string
  stack: Array<{
    line: number
    column: number
    filename: string
  }>
}

export function parseError(err: Error): ErrorMessage {
  // implement
}

solution

import { expect } from "chai";

interface Action<T> {
  payload?: T;
  type: string;
}

class EffectModule {
  count = 1;
  message = "hello!";
  delay(input: Promise<number>) {
    return input.then((i) => ({
      payload: `hello ${i}!`,
      type: "delay"
    }));
  }
  setMessage(action: Action<Date>) {
    return {
      payload: action.payload!.getMilliseconds(),
      type: "set-message"
    };
  }
}

// 修改 Connect 的类型,让 connected 的类型变成预期的类型
// type Connect = (module: EffectModule) => any;

// 1. 过滤出成员属性的函数 ✅
type FilterFunction<Obj> = {
  // 仅仅过滤 Function
  [K in keyof Obj]: Obj[K] extends Function ? K : never;
}[keyof Obj];

type Connect = (
  module: EffectModule
) => {
  // 2. 使用 infer 动态获取 参数类型
  [K in FilterFunction<EffectModule>]: EffectModule[K] extends (
    input: Promise<infer T>
  ) => Promise<Action<infer U>>
    ? (input: T) => Action<U>
    : EffectModule[K] extends (action: Action<infer T>) => Action<infer U>
    ? (action: T) => Action<U>
    : never;
  // 👎 input & action 形参必须写死 ???
};

/*
type Connect = (module: EffectModule) => {
  delay: (input: number) => Action<string>;
  setMessage: (action: Date) => Action<number>;
}
*/

const connect: Connect = (module) => ({
  delay: (input: number) => ({
    type: "delay",
    payload: `hello 2`
  }),
  setMessage: (input: Date) => ({
    type: "set-message",
    payload: input.getMilliseconds()
  })
});

type Connected = {
  delay(input: number): Action<string>;
  setMessage(action: Date): Action<number>;
};

export const test = connect(new EffectModule());
/*
type Connect = (module: EffectModule) => {
  delay: (input: number) => Action<string>;
  setMessage: (action: Date) => Action<number>;
}
*/

export const connected: Connected = connect(new EffectModule());


refs

LeetCode 面试题

https://github.com/LeetCode-OpenSource/hire

https://mp.weixin.qq.com/s/dWF9bPd9QhgsnuAHX33bNQ

https://github.com/LeetCode-OpenSource/hire/blob/master/foundations_zh.md

https://github.com/LeetCode-OpenSource/hire/blob/master/typescript_zh.md



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2020-09-03 23:11  xgqfrms  阅读(298)  评论(3编辑  收藏  举报