当前位置: 代码网 > it编程>编程语言>Javascript > TypeScript类型级别和值级别示例详解

TypeScript类型级别和值级别示例详解

2024年05月15日 Javascript 我要评论
对值级别编程类型级别编程区分首先,让我们对值级别编程和类型级别编程进行重要区分。值级别编程让我们编写将在生产中运行的代码即运行期,并为我们的用户提供有用的东西。类型级别编程帮助我们确保代码在发布之前即

对值级别编程类型级别编程区分

首先,让我们对值级别编程和类型级别编程进行重要区分。

  • 值级别编程让我们编写将在生产中运行的代码即运行期,并为我们的用户提供有用的东西。
  • 类型级别编程帮助我们确保代码在发布之前即编译期不包含错误,在运行期会被完全删除

javascript没有类型,所以所有javascript都是值级别的代码:

// a simple javascript function:
function sum(a, b) {
  return a + b;
}

typescript允许我们将类型注释添加到javascript中,并确保我们编写的sum函数永远不会用数字以外的任何东西调用:

// using type annotations:
function sum(a: number, b: number): number {
  return a + b;
}

但typescript的类型系统远比这强大得多。我们编写的真实代码有时需要是通用的,并接受我们事先不知道的类型。

在这种情况下,我们可以在尖括号<a,b,…>中定义类型参数然后,我们可以将类型参数传递给一个类型级函数,该函数根据输入类型计算输出类型:

// using type level programming:
function genericfunction<a, b>(a: a, b: b): dosomething<a, b> {
  return dosomething(a, b);
}

这就是类型级编程!dosomething<a,b> 是一种用特殊编程语言编写的类型级函数,它与我们用于值的语言不同,但同样强大。让我们将这种语言称为类型级typescript。

// this is a type-level function:
type dosomething<a, b> = ...
// this is a value-level function:
const dosomething = (a, b) => ...

类型级编程

类型级typescript是一种最小的纯函数语言。

在类型级别,函数被称为泛型类型:它们接受一个或多个类型参数并返回单个输出类型。下面是一个函数的简单示例,该函数使用两个类型参数并将它们包装在元组中:

type somefunction<a, b> = [a, b];
/*                ----    ------
                   ^         \
                  type        return type
               parameters
     \-------------------------/
                 ^
              generic
*/

类型级别的typescript没有很多功能。毕竟,它是专门为你的代码做类型约束的!也就是说,它确实有足够的特性(几乎)图灵完备,这意味着你可以用它解决任意复杂的问题。

  • 代码分支:根据条件执行不同的代码路径(相当于值级别if/else关键字)。
  • 变量赋值:声明一个变量并在表达式中使用它(相当于值级别var/let关键字)。
  • 函数:可重复使用的逻辑单位,如我们在前面的示例中看到的。
  • 循环:通常通过递归。
  • 相等检查:==但适用于类型!
  • 还有更多!

这是我们将在接下来的章节中学习的语言类型的简要概述。现在,让我们开始第一次挑战吧!

挑战是如何工作的

在每一章结束时,你将有一些挑战需要解决,以将你的新技能付诸实践。它们看起来像这样:

namespace challenge {
  // 1. implement a generic to get the union
  // of all keys in an object type.
  type getallkeys<obj> = todo;
  type res1 = getallkeys<{ a: number }>;
  type test1 = expect<equal<res1, "a">>;
}
  • namespace 是一个鲜为人知的typescript功能,它可以让我们在专用范围内隔离每个挑战。
  • todo 是占位符。这是您需要更换的!
  • res1=。。。 是泛型为某些输入类型返回的类型。您可以用鼠标将其悬停以检查其当前
  • type test1=expect<equal<res1,…>> 是类型级单元测试。用于判断todo部分的代码是否正确

在此之前你要先定义好expect和equal

type expect<t extends true> = t;
type equal<x, y> = (<t>() => t extends { [k in keyof x]: x[k]; } ? 1 : 2) extends <t>() => t extends { [k in keyof y]: y[k]; } ? 1 : 2 ? true : false;

挑战

准备好迎接你的第一个挑战了吗?出发:

/**
 * 1. the `identity` function takes a value of any type
 *    and returns it. make it generic!
 */
namespace genericfunction {
  function identity(a: todo): todo {
    return a;
  }
  let input1 = 10;
  let res1 = identity(input1);
  type test1 = expect<equal<typeof res1, number>>;
  let input2 = "hello";
  let res2 = identity(input2);
  type test2 = expect<equal<typeof res2, string>>;
}
/**
 * 2. `safehead` takes an array, a default value
      and returns the first element of the array
      if it isn't empty. make it generic!
 */
namespace safehead {
  function safehead(array: todo[], defaultvalue: todo): todo {
    return array[0] ?? defaultvalue;
  }
  let input1 = [1, 2, 3];
  let res1 = safehead(input1, 0);
  type test1 = expect<equal<typeof res1, number>>;
  let input2 = ["hello", "hola", "bonjour"];
  let res2 = safehead(input2, "hi");
  type test2 = expect<equal<typeof res2, string>>;
}
/**
 * 3. `map` transforms all values in an array to a value of
 *    different type. make it generic!
 */
namespace map {
  function map(array: todo[], fn: (value: todo) => todo): todo[] {
    return array.map(fn);
  }
  let input1 = [1, 2, 3];
  let res1 = map(input1, value => value.tostring());
  type test1 = expect<equal<typeof res1, string[]>>;
  let input2 = ["hello", "hola", "bonjour"];
  let res2 = map(input2, str => str.length);
  type test2 = expect<equal<typeof res2, number[]>>;
}
/**
 * 4. `pipe2` takes a value and pipes it into 2 functions
 *    sequentially. for example, `pipe2(x, f1, f2)` will
 *    result in `f2(f1(x))`. make it generic!
 *    
 */
namespace pipe2 {
  function pipe2(
    x: todo,
    f1: (value: todo) => todo,
    f2: (value: todo) => todo
  ): todo {
    return f2(f1(x));
  }
  let res1 = pipe2(
    [1, 2, 3],
    arr => arr.length,
    length => `length: ${length}`
  );
  type test1 = expect<equal<typeof res1, string>>;
  let res2 = pipe2(
    { name: 'alice' },
    user => user.name,
    name => name.length > 5
  );
  type test2 = expect<equal<typeof res2, boolean>>;
}

以上就是typescript类型级别和值级别示例详解的详细内容,更多关于typescript类型级别值级别的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com