Typescript高级: 详解 any、object、Object、Record<any, any> 和泛型 T

Ts总结2、any 类型,unknown 类型,never 类型(编译选项noImplicitAny) 阅读详情
AI摘要

本文详细解释了TypeScript中的any类型,它如何允许在编译时绕过类型检查,以及其带来的好处和潜在风险。讨论了泛型、object类型、类型守卫等概念,并提供了在实际开发中避免过度依赖any的建议和最佳实践。

any 类型

  • any 类型是 TypeScript 中一个特殊的类型,它表示可以是任意类型的值

  • 使用 any 类型会失去 TypeScript 的类型检查能力

  • 相当于告诉编译器“相信我,我知道这个值的类型”

  • 语法示例

    let anyVar: any;
    anyVar = 123;
    anyVar = "hello";
    anyVar = { name: "Alice" };
    
    // 使用 any 类型后,再用 is 来指定某一类型
    if (typeof anyVar === "string") {
        console.log(anyVar.toUpperCase()); // 编译器不会报错
    }
    
  • 在上面的例子中,anyVar 可以被赋值为任何类型的值

  • 在 if 语句中,我们使用了 JavaScript 的 typeof 操作符来检查 anyVar 是否为字符串类型

  • 如果是,则调用 toUpperCase() 方法,此时虽然使用了 any 类型

  • 但通过 is 类型的检查,我们仍然可以安全地使用字符串的方法

  • any 类型它允许你在编译时绕过类型检查

  • 换句话说,当你将一个变量声明为 any 类型时,你可以为它赋予任何类型的值

  • 并且TypeScript编译器不会对该变量进行类型检查

  • 这在你刚开始使用TypeScript或不确定某个变量的确切类型时非常有用

  • 但过度依赖 any 可能会使你的代码失去类型安全性,从而引入运行时错误

  • 应用any,在编译期可能会通过,但在运行时,可能会报错

    let value: any;
    
    value = "Hello, world!"; // 可以是字符串
    value = 42;             // 可以是数字
    value = true;           // 可以是布尔值
    value = { name: "Alice" }; // 可以是对象
    value = [1, 2, 3];      // 可以是数组
    value = null;           // 可以是null
    value = undefined;      // 可以是undefined
    
    // 调用任何方法或访问任何属性都不会引起编译错误
    value.someNonExistentMethod(); // 运行时可能会出错,因为方法可能不存在
    console.log(value.someNonExistentProperty); // 运行时可能是undefined,因为属性可能不存在
    
  • 注意事项

    • 虽然 any 类型非常灵活,但过度使用它会带来一些负面影响:
      • 失去类型安全性:使用 any 意味着你放弃了TypeScript提供的类型检查,这可能导致运行时错误,因为编译器不会为你捕获类型不匹配的问题
      • 可读性和可维护性降低:当代码中的变量或函数返回类型为 any 时,其他开发者可能不清楚这个变量的确切类型,从而增加了理解和维护的难度
      • 丧失类型推断:当你使用 any 类型时,TypeScript的类型推断功能将不再适用,因为编译器不会尝试推断 any 变量的更具体类型
  • 最佳实践

    • 避免使用 any:尽量使用具体的类型,而不是 any。这有助于捕获类型错误并增强代码的可读性和可维护性
    • 逐步替换 any:如果你正在处理一个大型代码库,并且其中已经使用了大量的 any,考虑逐步替换它们为更具体的类型。这可能需要一些时间和努力,但可以提高代码的质量
    • 使用类型守卫和类型断言:如果你确实需要处理不确定类型的值,可以考虑使用类型守卫(通过条件语句或类型谓词函数)来缩小类型的范围,或使用类型断言(as 语法)来明确告诉编译器你期望的类型
  • 使用类型守卫和类型断言示例

    function isNumber(value: any): value is number {
        return typeof value === 'number';
    }
    
    function processValue(value: any) {
        if (isNumber(value)) {
            // 在这个分支中,TypeScript知道value是number类型
            console.log(value * 2);
        } else {
            // 否则,value仍然是any类型
            console.log(value.toString()); // 这里可能需要进一步的类型检查或断言
        }
    }
    
    let someValue: any = 42;
    processValue(someValue); // 输出:84
    
    someValue = "Hello";
    processValue(someValue); // 输出:Hello
    
    // 使用类型断言
    let definitelyNumber: any = "This is not a number";
    let numberValue = definitelyNumber as number; // 这里不会有编译错误,但运行时可能会有问题
    console.log(numberValue * 2); // NaN 因为definitelyNumber实际上不是number
    
    function isString(value: any): value is string {
        return typeof value === "string";
    }
    
    function showValue(value: any) {
        if (isString(value)) {
            // 在这里,TypeScript 知道 value 是 string 类型
            console.log("Value is a string:", value.toUpperCase());
        } else {
            // 在这里,value 仍然是 any 类型,因为我们没有更多的信息来确定它的类型
            console.log("Value is not a string:", value);
        }
    }
    
    // 使用示例
    showValue("Hello"); // 输出: Value is a string: HELLO
    showValue(42); // 输出: Value is not a string: 42
    
  • 在使用类型断言时,你需要格外小心

  • 确保你确实知道变量在运行时的确切类型

  • 否则你可能会引入难以调试的运行时错误

object 类型

  • object 类型表示非原始类型,即不是 null、undefined、number、string、boolean 或 symbol 的类型
  • 当你想要表示一个变量可以是任何对象类型(但不包括原始类型)时,你可以使用 object 类型,这包括所有的对象,数组,函数等

1 )简单示例

let objVar: object;
objVar = {}; // 正确
objVar = []; // 正确
objVar = function() {}; // 正确
objVar = 123; // 编译错误: 不能将类型“number”分配给类型“object”。,因为 123 是 number 类型,不是 object

2 )使用对象字面量

let person: object = { name: "Bob", age: 25 }; // person 的类型是 { name: string; age: number; }

3 ) 使用索引签名

如果你想要一个对象,其属性可以是任何类型
但你知道这些属性都有一个共同的键类型,你可以使用索引签名

let dict: { [key: string]: string | number } = {}; // 任意字符串键,值类型为字符串或数字
dict["key1"] = "value1"; // 正确
dict["key2"] = 42; // 正确
// dict["key3"] = true; // 错误:不能将类型 'boolean' 分配给类型 'string | number'
console.log(dict) // { key1: 'value1', key2: 42 }

4 ) 与其他类型结合使用

  • 你也可以将 object 类型与其他类型结合使用,创建更复杂的类型
    type User = {
      id: number;
      name: string;
    } & object; // 确保 User 是 object 类型的一个子集,并且具有特定的属性
    
    const user: User = { id: 1, name: "Charlie" }; // 正确
    console.log(user)
    

5 ) 类型守卫与 object 类型

  • 虽然 object 类型本身不需要类型守卫,但如果你在处理联合类型

  • 并且想要区分一个值是否是对象,你可以使用类型守卫

    function isObject(item: any): item is object {
      return item !== null && typeof item === 'object';
    }
    
    function processValue(value: string | number | object) {
      if (isObject(value)) {
        // 在这里,TypeScript 知道 value 是 object 类型
        console.log(Object.keys(value));
      } else {
        // value 是 string 或 number 类型
        console.log(typeof value);
      }
    }
    
    processValue({ a: 1 }); // 输出对象的键
    processValue("hello"); // 输出 "string"
    
  • 注意:

    • 当使用 object 类型时,你应该确保你确实需要这个类型
    • 而不是更具体的类型,因为使用 object 类型会失去类型安全性
    • object 类型不包括数组,因为数组在 TypeScript 中是特殊的对象
    • 具有额外的属性和方法(如 length 和数组方法)
    • 如果你想要一个类型包括数组和所有其他对象
    • 你应该使用更宽松的类型,如 any 或创建一个联合类型,如 any[] | object
    • 当你想要确保一个对象具有某些特定的属性时
    • 最好使用接口或类型别名来定义这些属性,而不是简单地使用 object 类型
    • 这样可以提供更好的类型检查和代码可读性

Object 类型

  • 在 TypeScript 中,Object 实际上是指向 JavaScript 的全局 Object 构造函数的类型
  • 它是所有类型的超类型,包括原始类型如 string, number, boolean 等
  • 然而,直接使用 Object 类型通常不是一个好的实践,因为它会失去太多的类型信息
  • 是 JavaScript 的全局对象类型,不常用作 TypeScript 中的类型注解
  • 基本使用
    let obj: Object;
    
    obj = {}; // 空对象字面量
    obj = { name: "Alice", age: 30 }; // 对象字面量
    obj = [1, 2, 3]; // 数组(也是对象)
    obj = function() { console.log("Hello"); }; // 函数(也是对象)
    
    obj = 42; // 正确
    obj = "Hello"; // 正确
    obj = Symbol("1") // 正确
    // obj = undefined // 编译错误 Type 'undefined' is not assignable to type 'Object'.
    // obj = null // 编译错误 Type 'null' is not assignable to type 'Object'.
    console.log(obj)
    
    // 如果你确实需要一个可以包含任意键值对的对象
    // 你可以使用索引签名来定义一个更灵活的类型
    interface FlexibleObject {
      [key: string]: any;
    }
    
    let flexible: FlexibleObject = { name: "Charlie", age: 35, address: "123 Street" }; // 正确
    console.log(flexible) // { name: 'Charlie', age: 35, address: '123 Street' }
    

泛型 T

  • 泛型(Generics)是编程语言提供的一种特性
  • 它允许在定义函数、接口或类的时候,不预先指定具体的类型
  • 而在使用的时候再指定类型的一种特性
  • 在 TypeScript 中,泛型非常常用,它可以帮助我们编写可重用的组件
  • 这些组件可以支持多种类型的数据
  • T 是 TypeScript 中定义泛型时常用的一个类型变量
  • 它表示“Type”,即类型

1 ) 给泛型设定一个默认的类型

type DefaultToAny<T = any> = T extends unknown ? T : any;

function withDefaultAny<T = DefaultToAny>(value: T): T {
  return value;
}

// 使用示例
const str = withDefaultAny("hello"); // T 被推断为 string
const num = withDefaultAny(42); // T 被推断为 number
const anyValue = withDefaultAny({}); // T 默认为 any

console.log(str) // hello
console.log(num) // 42
console.log(anyValue) // {}
  • 在上面的代码中,DefaultToAny 类型是一个条件类型
  • 它接受一个泛型参数 T,并默认该参数为 any
  • withDefaultAny 函数使用了这个类型作为默认类型参数
  • 从而实现了当调用者没有提供泛型参数时,T 默认为 any 的效果

2 ) 一般使用

function firstElement<T>(arr: T[]): T | undefined {
    return arr.length > 0 ? arr[0] : undefined;
}

// 使用字符串数组
const strArr = ['a', 'b', 'c'];
const firstStr = firstElement(strArr); // T 被推断为 string,firstStr 的类型是 string | undefined

// 使用数字数组
const numArr = [1, 2, 3];
const firstNum = firstElement(numArr); // T 被推断为 number,firstNum 的类型是 number | undefined

// 也可以显式指定泛型参数
const explicitStr = firstElement<string>(['x', 'y']); // 显式指定 T 为 string
  • 在这个例子中,firstElement 函数使用了泛型 T 来表示数组元素的类型
  • 当我们传入一个字符串数组时,TypeScript 会自动推断出 T 是 string 类型
  • 同样地,如果传入一个数字数组,T 会被推断为 number 类型
  • 如果我们希望显式地指定泛型参数,也可以在调用函数时这样做
  • 泛型极大地增强了 TypeScript 的类型安全性和代码的复用性
  • 允许我们编写更加灵活和通用的代码
  • 泛型的好处
    • 编译期对类上调用方法或属性时的泛型类型进行安全检查(类型安全检查),不符合泛型实际参数类型(泛型实参类型) 就编译通不过,防止不符合条件的数据增加进来
    • 一种泛型类型被具体化成某种数据类型后,该数据类型的变量获取属性和方法时会有自动提示,这无疑提高代码开发效率和减少出错率
  • 泛型的特点
    • 定义时不明确使用时必须明确成某种具体数据类型的数据类型,这里体现出了泛型的宽泛
    • 编译期间进行数据类型安全检查的数据类型,这体现了泛型的严谨
    • 特别注意:
      • 1 ) 类型安全检查发生在编译期间
      • 2 )泛型是参数化的数据类型, 使用时明确化后的数据类型就是参数的值
  • 泛型类的格式: class 类名<泛型形参类型>
    • 泛型形参类型一般有两种表示
    • 1 )A-Z 任何一个字母
    • 2 )语义化的单词来表示
    • 绝大多数情况,泛型都是采用第一种形式表示,如下:
       class ArrayList<T> {  
            array: Array<T>
            add(data:T) {
                ...
            }
            ...
       }
      

Record<any, any> 类型

  • Record<K, T> 是 TypeScript 中的一个实用的内置工具类型,用于构造一个对象类型,其中对象的键类型为 K,值的类型为 T
  • 如果 K 是一个联合类型(union type),那么生成的对象的键可以是联合类型中列出的任何类型
  • 当你使用 Record<any, any>,你实际上是在创建一个可以接受任何键和任何值的对象类型
  • Record<any, any> 表示一个对象的键和值都可以是任意类型
  • 这与 { [key: string]: any } 索引签名非常相似,但 Record<any, any> 更加明确,并且利用了 TypeScript 的类型系统

1 )简单示例

let recordVar: Record<any, any>;
recordVar = { name: "Alice", age: 30 }; // 正确
recordVar = { pi: 3.14, sayHello: () => {} }; // 正确
recordVar = 123; // 错误,因为 123 不是对象

2 )复杂示例

// 定义一个类型,使用 Record<any, any>
type LooseObject = Record<any, any>;

// 创建一个 LooseObject 类型的变量
const obj: LooseObject = {
  aString: "Hello",
  aNumber: 42,
  aBoolean: true,
  anObject: { nested: "value" },
  anArray: [1, 2, 3],
  aSymbol: Symbol("unique"),
  // 可以添加任意类型的属性和值
};

// 访问属性(TypeScript 不会检查属性是否存在或类型是否正确)
console.log(obj.aString); // 输出: Hello
console.log(obj.aNumber); // 输出: 42

// 添加新属性(同样,TypeScript 不会检查类型)
obj.newProperty = "newValue";

// 试图访问一个不存在的属性,TypeScript 编译时不会报错,但运行时可能会是 undefined
console.log(obj.nonExistentProperty); // 输出: undefined
  • 注意
    • Record<any, any> 是一个非常宽松的类型
    • 它允许你在对象中添加任何键和任何值
    • 这类似于 JavaScript 中的普通对象,但在 TypeScript 中使用它会失去类型检查的好处
    • 由于 any 类型是 TypeScript 中的顶级类型,它可以被赋值给任何其他类型,反之亦然
    • 因此,使用 Record<any, any> 时,TypeScript 编译器不会对对象的属性进行类型检查
    • 尽管 Record<any, any> 在某些情况下可能很有用(例如,当你需要处理来自外部源的数据,且该数据的结构未知时),但在大多数情况下,最好避免使用它,以保持类型安全和代码的可维护性
    • 如果你知道对象的键和值的类型,最好显式地定义它们,而不是使用 Record<any, any>
    • 这样,TypeScript 可以为你提供更强的类型检查和更好的开发体验
    • 在实际开发中,应该尽可能地使用具体的类型而不是 any,以利用 TypeScript 提供的类型安全优势
    • 如果确实需要处理未知结构的数据,可以考虑使用类型守卫(type guards)或其他方式来逐步缩小类型的范围,以增加代码的健壮性

总结

1 )object 为什么不能替代类上的泛型

  • 1.1 编译期间 object 无法进行类型安全检查,而泛型在编译期间可以进行类型安全检查
    • object 接受也只能接受所有的 object 类型的变量
    • 比如有 Customer、Student、Dog 类的实例都是对象类型
    • 或者自己定义的对象,都可以传递给 object 类型的方法参数或属性
    • 但如果我们只希望添加Customer类的对象
    • 当添加其他类的对象必须出现编译错误
    • 但是 object 无法做到,就只能用泛型了
  • 1.2 object 类型数据无法接受非 object 类型的变量,只能接受 object 类型的变量,泛型能轻松做到
    • 正因为 object 接受也只能接受所有的 object 类型的变量
    • 那么如果有一个集合类[数组封装类]有一个 add 方法
    • 允许每次添加指定类型的变量到 add 方法的参数
    • 比如
      • 我们第一轮的希望添加 10 次字符串类型的变量
      • 第二轮的希望添加 10 次整数类型变量
      • 第三轮的希望添加 10 次顾客类型的变量,泛型轻松做到
    • object 类型数据无法接受任意非 object 类型的变量,object 只能接受所有的 object 类型的变量
  • 1.3 object 类型数据获取属性和方法时无自动提示,泛型有自动提示
    • 一种泛型类型被具体化成某种数据类型后,该数据类型的变量获取属性和方法时会有自动提示,提高代码开发效率和减少出错率
    • 但在 object 类型的变量无法获取数据类型的属性和方法,降低了体验感和开发效率

2 ) any 为什么不能替代类上的泛型

  • 编译期间 any 无法进行类型安全检查,而泛型在编译期间可以进行类型安全检查
    • any 是所有类型的父类,也是所有类型的子类
    • 如果我们现在是一个宠物店类
      • 希望只能添加 Dog 类
      • 当调用 add 方法添加 Customer、Student 类必定出现编译错误
      • 从而保证了类型安全检查
    • 但是 any 类型无法保证类型安全检查,可以为任意类型
      • 包括 string,number,boolean,null,undefined,never,void,unknown 基础数据类型
      • 和数组,类,接口类型, type 类型的变量全部能接受
      • 不会进行无法进行类型安全检查
  • any 类型可以获取任意数据类型的任何属性和任意方法而不会出现编译错误导致潜在错误风险,而泛型却有效的避免了此类问题发生
    • any 类型可以获取任何属性和任意方法而不会出现编译错误,因为any可以代表任意数据类型来获取任意属性和任意方法
    • 但是泛型类型被具体化成某种数据类型后,该数据类型的变量调用该数据类型之外的属性和方法时,出现编译错误,这也减少了代码隐藏潜在错误的风险
  • any 类型数据获取属性和方法时无自动提示,泛型有自动提示
  • any 类型可以代表任意数据类型来获取任何属性和任意方法而不会出现编译错误
    • 因为any可以代表任意数据类型来获取任意属性和任意方法
    • any 的这个特性是一把双刃剑,当我们需要这么使用
    • 它给我们带来方便,但是大多数情况下我们是不需要这么做的
深入理解 TypeScript 中的 any 类型:使用场景与最佳实践 TypeScript 提供了一个特殊的 any 类型,它既是强大的逃生舱口,也可能是类型安全的突破口。本文将全面剖析 any 类型的本质、适用场景、潜在风险以及替代方案,帮助开发者在保持类型安全的同时灵活应对各种复杂场景。 阅读详情

相关推荐

TS - 类型any[] , 遍历报错

如果你能明确知道变量的类型,最好使用更具体的类型,以便 TypeScript 编译器进行类型检查。如果你不确定变量的类型,可以使用。可以存储任何类型的元素,但是在 TypeScript 中,它不会提供数组原生的方法,例如。方法,你需要先将其转换为一个具有数组原生方法的类型。类型是一个特殊的类型,它可以被赋值为任何类型的值,也可以赋值给任意类型。类型,它允许分配任何类型的值,但在使用之前需要进行类型检查。时,它表示这个数组可以包含任意类型的值。转换为一个特定类型的数组,然后再使用。类型的数组,然后使用。

weixin_43133668的博客 1027

使用 TypeScript 中的 any 类型前,你需要了解的一切

点击上方三分钟学前端,关注公众号回复交流,加入前端编程面试算法每日一题群面试官也在看的前端面试资料any在 TypeScript 中,任何类型的值都可以赋值给 any , any 也可以...

我本可以容忍阳光,如果我不曾见过太阳,然而阳光已使我荒凉,成为更新的荒凉。 8076

TypeScript进阶:Record与ReturnType等泛型工具实战解析

在软件开发中,类型系统是确保代码质量和可维护性的重要基石,其核心原理在于通过静态检查将运行时错误提前至编译时发现。TypeScript作为JavaScript的超集,通过强大的类型系统提供了这一能力,其中泛型工具是实现类型安全与灵活性的关键技术。这些工具允许开发者构建可复用、自描述的类型约束,显著提升大型应用(如React、Vue前端项目或Node.js后端服务)的工程实践质量。具体而言,Record工具用于构建类型安全的字典与配置对象,它能严格约束对象的键值对结构;ReturnType工具则能精准捕获函数

java2000.net 576

精进TypeScript--你了解any类型吗?

Typescript中的any类型有效地静默了类型检查器和Typescript语言服务。它会掩盖真正的问题,有损于开发者体验,并破坏开发者对类型系统的信心。因此,尽量避免使用它!

liu888663的博客 1402

YOLOv8模型INT8量化实战:解决sigmoid输出归零的坑(附代码修改)

本文详细介绍了YOLOv8模型INT8量化过程中遇到的sigmoid输出归零问题及其解决方案。通过修改模型导出代码、优化ONNX量化流程,并提供完整的部署优化技巧,帮助开发者在边缘计算设备上实现高效的模型推理。文章还包含量化效果验证和常见问题排查方法,助力开发者快速解决实际部署中的难题。

vvv99的博客 253

DAP-Link DIY复刻指南

DAP-Link是ARM开源的一个项目,主要用于代码下载以及调试,支持SWD和JTAG调试接口,对于开发嵌入式的同学相信都或多或少有所耳闻。除了DAP-Link之外还有很多同类型的调试器,如ST-LinkJ-Link,但是这些都是不开源的,无法复刻或进行二次开发。但DAP-Link不同,完全开源,不用担心侵权问题,且随着开源社区大家的共同努力,DAP-Link经过了不断的迭代,先如今已取代ARM之前推出的CMSIS-DAP开源项目。

爱出名的狗腿子 1万+

TypeScript进阶:Record与ReturnType泛型工具实战解析

在TypeScript类型系统中,泛型工具是提升代码类型安全性和灵活性的核心机制。其原理在于通过类型参数化,实现类型的抽象与复用,从而在编译时捕获更多潜在错误。Record和ReturnType作为内置工具类型,具有重要的技术价值:Record能基于已知键集合构建结构确定的对象类型,常用于数据字典和配置映射;ReturnType则能提取函数返回类型,实现类型推导与同步。在工程实践中,它们广泛应用于构建类型安全的API层、状态管理中的Action推导,以及动态表单配置生成等场景。掌握这些工具,能显著提升大型前

weixin_34413103的博客 325

从零开始:MTK ISP调试中的ImagiqSimulator实战指南

本文详细介绍了MTK ISP调试中ImagiqSimulator的实战应用,从环境准备、参数加载到核心模块调整,提供全面的调试流程指南。重点讲解了DM模块参数优化技巧和常见问题解决方案,帮助工程师高效完成ISP调试工作,提升图像处理质量。

weixin_29168813的博客 491

ts定义对象类型Record<string, any>;和object、Object的区别

object对象上,键不会被假定为any,TypeScript不知道哪些密钥实际存在,但它不允许访问任何密钥。TypeScript允许访问类型Record对象得任何属性,即使特定键未知。object定义是一个对象类型,不能自动获取对象上的属性和方法。Object 也是不可以自动获取定义的对象上的属性和方法,object类型只能定义对象类型,不能定义其他类型。Object只能赋给任意值,不能调用方法。但是可以获取对象自身上的属性和方法。Object类型可以定义任何类型。

吴冬雪的博客 8534

从零开始Cubemx配置STM32搭载freeRTOS以及lwip实现tcp网络通信(二)

Cubemx配置LWIP,实现网络通信

qq_30623327的博客 1万+

小米手机安装Burp证书失败原因与DER格式改造指南

CA证书是HTTPS抓包和移动安全测试的基础组件,其本质是遵循X.509标准的数字凭证,依赖ASN.1/DER编码格式与完整证书链实现可信验证。Android系统默认支持PEM和DER两种编码,但MIUI自14版本起强化安全策略,仅识别DER二进制格式,并强制校验Subject Alternative Name(SAN)、Basic Constraints及证书链完整性。这种企业级加固逻辑导致Burp Suite导出的PEM格式.cer文件在小米设备上‘安装成功但无效’。本文聚焦证书格式转换、SAN字段注入

weixin_33646989的博客 625

TypeScript(四)泛型编程

TypeScript泛型编程 映射类型 内置工具 与类型体操

聪明勇敢有力气的博客 538

前端零代码丨UIOTOS + NodeRed:无代码搭建工控上位机的绝配组合!

用户类型价值硬件产品商软硬一体方案,无代码GUI上位机成新卖点软件服务商售前原型演示利器,交付成本降低至1/3平台开发商融合无代码技术,同质化竞争中脱颖而出🚀 总结UIOTOS的前端零代码设计(页面嵌套、属性继承、节点连线)与NodeRed的后端流程自动化,堪称工控与IoT开发的黄金组合。无论是串口通信、SCADA监控还是业务管理,均能实现“无代码交付”,真正让前端不求人,硬件交互触手可及!探索更多案例:UIOTOS官网在线体验。

2502_91192798的博客 757

如何理解type Record<K extends keyof any, T>

Record的完整定义如下 type Record<K extends keyof any, T> = { [P in K]: T; }; 首先要先理解keyof any是啥。 type KEY = keyof any //即 string | number | symbol 因为不管什么类型,它的key总是string,number,symbol中的一种。 let a: any; a['a'] //ok a[0] // ok a[Symbol()] //ok a[{}] // e

qq_36503569的博客 4144

从0到1:用Claude 3.7十日拿下教育部课题申报书(附可修改LaTeX模板)

🟣"作为教育部人文社科项目评审专家,请根据近三年立项数据分析,为[您的学科方向]领域推荐5个具有创新性且符合'十四五'规划的重点选题,要求选题体现交叉学科特征,并标注潜在理论突破点"🟣"根据前期研究基础,创建包含4个研究模块、12个关键节点的三维技术路线图,要求体现实验仿真-实证研究-理论建模的螺旋递进关系,并标注每个节点的预期成果形态"🟣"现在切换至教育部学科评审组组长模式,从选题价值、创新程度、研究可行性三个维度对本申报书进行盲审,生成包含9个扣分风险点的诊断报告及修改优先级排序"

智能AI让学术科研更容易 545

YOLOv8改进策略【损失函数篇】| 2024 引进Focaler-IoU损失函数 加强边界框回归 (Focaler-DIoU、Focaler-GIoU、Focaler-CIoU)

本文记录的是改进YOLOv8的损失函数,将其替换成。现有研究通过利用边界框之间的几何关系来提高回归性能,但忽略了困难样本和简单样本分布对边界框回归的影响。不同检测任务中困难样本和简单样本的分布不同,对于简单样本占主导的检测任务,关注简单样本的边界框回归有助于提高检测性能;对于困难样本比例较高的检测任务,需要关注困难样本的边界框回归。,提高检测器在不同检测任务中的性能。实现的。

Limiiiing的博客 1223

TypeScript 泛型工具实战:3 种高级模式构建可复用 React 组件类型

本文深入探讨了TypeScript泛型工具在React组件开发中的高级应用,通过Pick、Omit、Partial和Record等核心工具,实现精确控制Props、动态表单状态切换和配置化组件等三大典型场景,显著提升代码的类型安全性和可复用性。

agcozdwdfvds08078的博客 358

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

TypeScript高级用法

首选看 extends 后面的内容,{t: infer Test}可以看成是一个包含t属性的类型定义,这个t属性的 value 类型通过infer进行推断后会赋值给Test类型,如果泛型实际参数符合{t: infer Test}的定义那么返回的就是Test类型,否则默认给缺省的string类型。infer 的中文是“推断”的意思,一般是搭配上面的泛型条件语句使用的,所谓推断,就是你不用预先指定在泛型列表中,在运行时会自动判断,不过你得先预定义好整体的结构。与||的功能是相似的,区别在于?

qq_37609418的博客 1836

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

TypeScript { [key: string]: unknown } 索引签名写法和 Record 替代

本文解析了TypeScript中{ [key: string]: unknown }类型的使用方法。该类型表示键为字符串、值为任意类型的对象,其中unknown强制类型检查,比any更安全。文章介绍了其语法结构、与Record<string, unknown>的等价性,并列举了字典结构、处理JSON数据、泛型约束等应用场景。同时指出关键限制:当对象包含固定属性时,索引签名的值类型必须兼容这些属性类型,建议使用联合类型或交叉类型解决类型冲突问题。通过强制类型检查,这种写法能有效提升代码的安全性。

363045841的博客 666

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Axios TypeScript 类型系统详解:模块解析、错误 Type Guard 与泛型化请求配置(axios)

本文为 axios(Promise based HTTP client for the browser and node.js)TypeScript 支持的技术指南,围绕其官方文档 [docs/fr/pages/advanced/type-script.md](https://link.gitcode.com/i/9546f6e9bd7f3ea0503d0b084ec9bed8) 的核心内容展开。

gitblog_01151的博客 771

TypeScript内置类型一览(Record<string,any>等等)

TypeScript中Record是啥?现在让我们来了解一下TypeScript官方的内置类型,让你的开发效率再上一层楼。

球球不吃虾WHR2349博客 6810

React Final Form 强类型表单值:用 TypeScript 泛型构建类型安全的 Field 输入组件体系

`react-final-form` 的 `Field` 组件支持在 JSX 上直接标注泛型类型,从而让表单字段值、输入组件 props 与提交回调之间形成一条完整的类型链。本文以仓库 `examples/strongly-typed-values-typescript` 示例为核心,完整讲解如何定义强类型的表单值模型、如何通过 `<Field<string> / <Field<number> /

gitblog_00434的博客 680

TypeScript中的泛型工具

原文链接:https://juejin.cn/post/6844904147167215624#heading-1 本期涉及的操作符如下: Partial Required Readonly Pick<T,K extends keyof T> Record<K extends keyof any, T> Exclude<T,U> Extract<T,U> Omit<T, K extends keyof any> 首先还是先讲述一.

冰雪为融的博客 719

告别 TypeScript `any` 类型:用 unknown、泛型与类型守卫重构类型安全(Front-End-Checklist no-explicit-any 规则实战)

> 本文基于 Front-End-Checklist 仓库中的 [no-explicit-any 规则文档](https://link.gitcode.com/i/1262248d0a5ecfa5891eedb1109328f1) 编写。该规则属于仓库前端质量规则体系(`javascript/quality` 分类)中的一项中级实践:`any` 是 TypeScript 的逃生舱,它会关闭编译器对

gitblog_00471的博客 256

《The Concise TypeScript Book》泛型深度指南:从通用函数到类型约束与上下文收窄

泛型(Generics)是 TypeScript 类型系统的核心能力之一,它允许你编写能够适用于多种类型的可复用组件、函数、类和接口。本文以开源仓库 typ/typescript-book 中 [泛型章节](https://link.gitcode.com/i/df88f8eec18df4a4f882cc42c63f7ca2) 为主线,结合仓库内 `class.md`、`exploring-the

gitblog_00210的博客 157

TypeScript 3.4 破坏性变更全解析:从顶级 `this` 类型化到泛型推断升级

TypeScript 3.4 是语言演进中一个承前启后的版本:它在引入 `--incremental` 增量编译、`as const` 断言、`readonly` 元组等新特性的同时,也带来了一批需要开发者注意的**破坏性变更(Breaking Changes)**。本文以本仓库 [zh/breaking-changes/typescript-3.4.md](https://link.gitcod

gitblog_00132的博客 380
上一篇: Typescript高级: 对泛型和多态的应用, 实现Java中的ArrayList和LinkedList
下一篇: Go微服务: Prometheus性能监控与Grafana平台的搭建
Wang's Blog
博客等级 码龄12年 7433粉丝 2419原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值