search
HomeWeb Front-endJS TutorialShare a good TS interview question (including 3 levels) and see which level you can answer!

Share a good TS interview question (including 3 levels) and see which level you can answer!

I recently came across a good TS interview question and would like to share it.

This question has 3 levels, let’s look at them one by one.

The requirements for the first level are as follows:

Implement a zip function to merge the elements of two arrays in order, such as input [1,2,3] , [4,5,6], return [[1,4], [2,5],[3,6]]

This layer is to fetch from two arrays each time After merging an element, put it into the array, and then continue processing the next one, and continue this process recursively until the array is empty.

function zip(target, source) {
  if (!target.length || !source.length) return [];

  const [one, ...rest1] = target;
  const [other, ...rest2] = source;

  return [[one, other], ...zip(rest1, rest2)];
}

The result is correct:

The first level is relatively simple, then let’s look at the second level requirements:

Define the ts type for this zip function (two writing methods)

There are two forms of function definition:

Declare the function directly through function:

function func() {}

And declare an anonymous function and assign it to a variable:

const func = () => {}

The types of parameters and return values ​​are both arrays, but the specific types are not known, so you can write unknown[].

So the definition of the two function types is like this:

is also a direct function declaration of function type and interface declaration The function type is then added to the variable type both ways.

Because the specific element type is not known, unknown is used.

You may ask here the difference between any and unknown:

Both any and unknown can receive any type:

But any can also Assign to any type, but unknown.

This is only used to receive other types, so unknown is more appropriate and safer than any.

This level is also relatively basic ts syntax, and the third level becomes more difficult:

Use type programming to achieve precise type hints, such as passing parameters in [1, 2,3], [4,5,6], then the type of the return value should be prompted as [[1,4], [2,5],[3,6]]

here If the return value type is required to be precise, we must dynamically generate the return value type based on the type of the parameter.

That's it:

Declare two type parameters Target and Source, and the constraint is unknown[], which is an array type of any element type.

These two type parameters are the types of the two parameters passed in.

The return value is calculated by Zip.

Then we need to implement the advanced type of Zip:

The type parameters passed in are two array types, and we also need to extract each element from them and merge them together.

Pattern matching can be used to extract elements:

So this type can be defined like this:

type Zip<One extends unknown[], Other extends unknown[]> =
    One extends [infer OneFirst,...infer Rest1]
      ? Other extends [infer OtherFirst, ...infer Rest2]
        ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]
        : []
      : [];

Extract the first elements of the two arrays respectively and construct a new array. Then do this recursively for the remaining array until the array is empty.

This achieves the advanced type we want:

#But if you add it as a return value to the function, an error will be reported:

Because we don’t know what the parameters are when we declare the function, we naturally cannot calculate the value of Zip, so there will be a type mismatch here:

then what should we do?

can be solved by function overloading:

#ts supports function overloading. You can write the type definition of multiple types of functions with the same name, and finally write the function's Implementation, so that when this function is used, the function type will be matched according to the type of the parameter.

The function we use type programming will not report an error if it is written in this way.

Let’s take a look:

Why is the return value type wrong?

#In fact, the matching function type is correct at this time, but the deduced type is not a literal type.

You can add as const at this time.

But adding as const will deduce readonly [1,2,3]

This type is not It matches, so we need to add readonly:

to the declaration of the type parameter, but the type of the Zip function does not match again.

Should we add readonly to all places where this type is used?

No need, can we just remove the readonly modification?

Typescript has a built-in advanced type readonly:

You can add readonly modification to each index of the index type:

But there is no advanced type that removes the readonly modification. We can implement it ourselves:

Use the mapping type syntax to construct a new index type. Adding -readonly means removing the readonly modification.

#Some students may ask, is the array type also an index type?

Yes, the index type is a type that aggregates multiple elements, so objects, arrays, and classes are all.

So we can naturally use it on arrays:

(To be precise, it’s called a tuple. A tuple has a fixed number of elements. Array)

Then we only need to use Mutable to remove readonly before passing in the Zip:

Let’s try again:

Done! Now the return value type is correct.

But there is still a problem. If the literal is not passed in directly, the literal type cannot be deduced. At this time, something seems wrong:

But don’t we all declare overloaded types?

If the literal type cannot be deduced, it should match this:

But in fact it matches the first one:

At this time, you only need to change the order of the two function types:

At this time, the situation of literal parameters is still correct:

Why?

Because the types of overloaded functions are matched from top to bottom, as long as one is matched, it will be applied.

In the case of non-literal values, the type is number[], which can match the type of unknown[], so that function type takes effect.

In the case of literals, the derivation is readonly [1,2,3], with readonly so it does not match unknown[], and continues to match, just The function type with type parameters was matched.

In this way, the appropriate function type is applied in both cases.

The whole code is like this:

type Zip<One extends unknown[], Other extends unknown[]> = One extends [
  infer OneFirst,
  ...infer Rest1
]
  ? Other extends [infer OtherFirst, ...infer Rest2]
    ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]
    : []
  : [];

type Mutable<Obj> = {
  -readonly [Key in keyof Obj]: Obj[Key];
};

function zip(target: unknown[], source: unknown[]): unknown[];

function zip<Target extends readonly unknown[], Source extends readonly unknown[]>(
  target: Target,
  source: Source
): Zip<Mutable<Target>, Mutable<Source>>;

function zip(target: unknown[], source: unknown[]) {
  if (!target.length || !source.length) return [];

  const [one, ...rest1] = target;
  const [other, ...rest2] = source;

  return [[one, other], ...zip(rest1, rest2)];
}

const result = zip([1, 2, 3] as const, [4, 5, 6] as const);

const arr1 = [1, 2, 3];
const arr2 = [4, &#39;5&#39;, 6];

const result2 = zip(arr1, arr2);

ts playground 地址

总结

今天我们做了一道综合的 ts 面试题,一共有三层:

第一层实现 js 的逻辑,用递归或者循环都能实现。

第二层给函数加上类型,用 function 声明类型和 interface 声明函数类型两种方式,参数和返回值都是 unknown[]。

第三层是用类型编程实现精准的类型提示,这一层需要拿到参数的类型,通过提取元素的类型并构造出新的数组类型返回。还要通过函数重载的方式来声明类型,并且要注意重载类型的声明顺序。

as const 能够让字面量推导出字面量类型,但会带有 readonly 修饰,可以自己写映射类型来去掉这个修饰。

其实这也是我们学习 ts 的顺序,我们先要能把 js 逻辑写出来,然后知道怎么给函数、class 等加 ts 类型,之后学习类型编程,知道怎么动态生成类型。

其中类型编程是 ts 最难的部分,也是最强大的部分。攻克了这一层,ts 就可以说学的差不多了。

【相关推荐:javascript学习教程

The above is the detailed content of Share a good TS interview question (including 3 levels) and see which level you can answer!. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

From C/C   to JavaScript: How It All WorksFrom C/C to JavaScript: How It All WorksApr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Have Crossplay?
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool