Skip to content

for-of over a dynamically-typed string throws (string).next is not a function — next string-width wall after #4889 #4892

@proggeramlug

Description

@proggeramlug

Summary

for...of over a string value whose static type is unknown (any, or a value flowing out of an iterator/destructure) throws at runtime:

TypeError: (string).next is not a function

Statically-typed for-of over strings works fine — the failure needs the dynamic path, where for-of routes through the generic iterator protocol (js_get_iterator, #4786 lazy for-of) and apparently gets the string itself back as the "iterator", so the subsequent .next() call lands on a plain string. Same family as the pre-existing ".entries()-on-any → next is not a function" note from the #4800 investigation.

Repro (fails on the #4889 / PR #4891 build)

function f(v: any) {
  let n = 0;
  for (const ch of v) { n++; }
  return n;
}
console.log(f("ab")); // Node: 2 — Perry: TypeError: (string).next is not a function

Also reachable without any, via destructured iterator results:

const seg = new Intl.Segmenter();
for (const { segment } of seg.segment("a👍b")) {
  for (const ch of segment) {}   // throws on the first segment
}

A statically-typed control works (so this is the dynamic-value dispatch, not string iteration itself):

function g(seg: string) {
  const v = seg.replace(/^x+/, "");
  for (const ch of v) {}  // OK
}

Impact

With #4889 fixed (PR #4891), string-width@7+ passes module init and returns correct widths for pure-ASCII and pure-emoji inputs (stringWidth("abc")=3, stringWidth("👍")=2, stringWidth("👨‍👩‍👧")=2 ✅). But any mixed string (stringWidth("a👍b")) reaches hangulClusterWidth(), which does for (const character of visibleSegment) on a segmenter-derived (dynamically-typed) string → throws. So this is now the live string-width → wrap-ansi / cli-truncate / slice-ansi → ink (#348) blocker on the string-handling side.

Expected

For-of over any string value drives the String iterator (code points): f("ab") → 2, and stringWidth("a👍b") → 4 (Node-verified).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions