You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript动态类型声明错误修复技术求助

Fixing TypeScript Generic Indexing Errors in Nested Object Access Function

Let's break down what's going wrong with your function and fix both errors step by step.

Understanding the Issues

Your code aims to create a function that takes a two-element array (a top-level key of a, plus a second-level key of that property) to access nested values. The problems stem from how you structured your generics:

  1. Error 1: Type 'keyof D' cannot be used to index type '{ a: string; b: string; c: { k: string; }; }[K]'

    • You defined D as a separate generic extending ObjType[K], but TypeScript can't track the direct relationship between D and ObjType[K] when K is a union type. This means keyof D might not be valid for all possible types in ObjType[K], so TypeScript blocks the index operation to avoid unsafe access.
  2. Error 2: Type "k" is not assignable to type 'number | "toString" | ...'

    • When you pass ['a', 'k'], K is inferred as "a", so ObjType[K] is string. The keyof string includes all string methods (like toString) and numeric indices—"k" isn't part of that set, hence the error. Worse, your original generic setup didn't prevent this invalid call from being allowed in the first place.

The Fix

We can simplify the generics to directly link the second argument's type to the first argument's corresponding property. Here's the corrected code:

const a = { a: 'value 1', b: 'value 2', c: { k: 'value 3' } };
type ObjType = typeof a;

// Simplify generics: only bind K, derive the second argument's type from ObjType[K]
function funArray<K extends keyof ObjType>(arg: [K, keyof ObjType[K]]) {
  const oneLvl = a[arg[0]];
  const secondLvl = oneLvl[arg[1]]; // No more indexing error!
  console.log(secondLvl);
}

funArray(['c', 'k']); // Works as expected
// funArray(['a', 'k']); // Now throws a helpful error (correct behavior: 'k' isn't a valid key for string)

Why This Works

  • Eliminates redundant generics: By removing D, we directly tie the second argument's type to keyof ObjType[K]—TypeScript now knows exactly which keys are valid for the property selected by K.
  • Fixes indexing safety: oneLvl is typed as ObjType[K], and arg[1] is typed as keyof ObjType[K], so indexing is guaranteed to be valid.
  • Blocks invalid calls: The function now correctly rejects calls like funArray(['a', 'k']) because "k" isn't a valid key for a string type—this is a good thing, since accessing a.a.k would be a runtime error anyway.

Optional: Restrict to Nested Object Properties

If you only want to allow calling the function with top-level keys that point to objects (not strings), you can add a conditional type to narrow down valid K values:

// Only allow K where ObjType[K] is an object
type ObjectKeys<T> = { [K in keyof T]: T[K] extends object ? K : never }[keyof T];

function funArray<K extends ObjectKeys<ObjType>>(arg: [K, keyof ObjType[K]]) {
  const oneLvl = a[arg[0]];
  const secondLvl = oneLvl[arg[1]];
  console.log(secondLvl);
}

funArray(['c', 'k']); // Still works
// funArray(['a', 'k']); // Throws an error immediately (since 'a' isn't an ObjectKey of ObjType)

This version makes the function even stricter, ensuring you can only pass keys that lead to nested objects.

内容的提问来源于stack exchange,提问作者Andriy Bek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:22:33