text:
Incorrect circularity detection

TypeScript Version:  3.6.2
Search Terms:

7022
directly or indirectly in its own initializer

Code
function extent(nums: number[]) {
  let result: [number, number] | null = null;
  for (const num of nums) {
    if (!result) {
      result = [num, num];
    } else {
      const [oldMin, oldMax] = result;
      result = [Math.min(num, oldMin), Math.max(num, oldMax)];
    }
  }
  return result;
}

Expected behavior:
No error.
Actual behavior:
'oldMin' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)
'oldMax' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)

I'm really struggling to see where the circularity comes in. The type of result is shown as [number, number] in that branch, so I'd assume destructuring it would result in two number types.
Removing the destructuring and using array accesses is equivalent but produces no error:
function extent(nums: number[]) {
  let result: [number, number] | null = null;
  for (const num of nums) {
    if (!result) {
      result = [num, num];
    } else {
      result = [Math.min(num, result[0]), Math.max(num, result[1])];  // ok
    }
  }
  return result;
}

Playground Link:  link
Related Issues:

https://github.com/microsoft/TypeScript/issues/32950

here's another example from zone (source file wtf.ts):
  function shallowObj(obj: {[k: string]: any} | undefined, depth: number): any {
    if (!obj || !depth) return null;
    const out: {[k: string]: any} = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        let value: any = obj[key];
        switch (typeof value) {
          case 'object':
            const name = value && value.constructor && (<any>value.constructor).name;
            value = name == (<any>Object).name ? shallowObj(value, depth - 1) : name;
            break;
          case 'function':
            value = value.name || undefined;
            break;
        }
        out[key] = value;
      }
    }
    return out;
  }

Gives:
zone.js/lib/zone-spec/wtf.ts:134:13 - error TS7022: 'value' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

134         let value = obj[key];
                ~~~~~

Another example i've just come across:
function testFunction() {
  let state: { value: number } | null = null;
  for (let i = 0; i < 10; i++) {
    const previousState = state;
    //    ^^^^^^^^^^^^^ error: 'previousState' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)
    state = null;

    const value = i === 0 ? 0 : previousState?.value;
    //    ^^^^^ error: 'value' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)

    if (value !== undefined) {
      state = { value: value + 1 }
    }
  }
  console.log('Test Function:', state?.value);
}

When putting in explicit type annotations, it produces a new error:
function testFunction() {
  let state: { value: number } | null = null;
  for (let i = 0; i < 10; i++) {
    const previousState: { value: number } | null = state;
    state = null;

    const value: number | undefined = i === 0 ? 0 : previousState?.value;
    //   Property 'value' does not exist on type 'never'.ts(2339): ^^^^^
    if (value !== undefined) {
      state = { value: value + 1 }
    }
  }
  console.log('Test Function:', state?.value);
}

Here's another case, but then with  a while loop:
interface Node {
  next: Node | null;
}

function test(node: Node) {
  let currentNode: Node | null = node;
  while (currentNode !== null) {
    const nextNode = currentNode.next;
    //    ~~~~~~~~ error TS7022: 'nextNode' implicitly has type 'any' because it does not have a type annotation
    //                           and is referenced directly or indirectly in its own initializer.
    currentNode = nextNode;
  }
}

Playground link

Here's another case, but then with  a while loop:
interface Node {
  next: Node | null;
}

function test(node: Node) {
  let currentNode: Node | null = node;
  while (currentNode !== null) {
    const nextNode = currentNode.next;
    //    ~~~~~~~~ error TS7022: 'nextNode' implicitly has type 'any' because it does not have a type annotation
    //                           and is referenced directly or indirectly in its own initializer.
    currentNode = nextNode;
  }
}

Playground link

BTW, using @JoostK's example, if you removes the asignation, error goes away... 😆
interface Node {
  next: Node | null;
}

function test(node: Node) {
  let currentNode: Node | null = node;
  while (currentNode !== null) {
    const nextNode = currentNode.next; // No error
   // currentNode = nextNode; // Uncomment it, and error comes back
    console.log(nextNode);
  }
}

BTW, using @JoostK's example, if you removes the asignation, error goes away... 😆
interface Node {
  next: Node | null;
}

function test(node: Node) {
  let currentNode: Node | null = node;
  while (currentNode !== null) {
    const nextNode = currentNode.next; // No error
   // currentNode = nextNode; // Uncomment it, and error comes back
    console.log(nextNode);
  }
}

BTW, using @JoostK's example, if you removes the asignation, error goes away... 😆

Removing the assignment removes the circular nature of currentNode, so that's expected. It's ends up being circular due to the involvement of flow typing.

BTW, using @JoostK's example, if you removes the asignation, error goes away... 😆

Removing the assignment removes the circular nature of currentNode, so that's expected. It's ends up being circular due to the involvement of flow typing.

A new one in 4.7.0-beta https://github.com/microsoft/TypeScript/issues/48708

The error also goes away if you simply move just the initialization out of the loop:
function extentOne(nums: number[]) {
  let result: [number, number] | null = null;
  let oldMin, oldMax;
  for (const num of nums) {
    if (!result) {
      result = [num, num];
    } else {
      [oldMin, oldMax] = result;
      result = [Math.min(num, oldMin), Math.max(num, oldMax)];
    }
  }
  return result;
}

It also goes away if you remove null from the type:

function extentTwo(nums: number[]) {
  if (nums.length === 0) {
    return null
  }
  let result: [number, number] = [nums[0], nums[0]];
  for (const num of nums) {
    if (!result) {
      result = [num, num];
    } else {
      const [oldMin, oldMax] = result;
      result = [Math.min(num, oldMin), Math.max(num, oldMax)];
    }
  }
  return result;
}

Playground link

I went to take a look at this old issue today, only to find that @babakks had recently fixed it in #56753. Nice! 🎉
The example in the original issue already works on the TS 5.4-beta playground and the fix should be out in the final 5.4 release in the next few weeks.

Unfortunately there's still a limitation for https://github.com/microsoft/TypeScript/issues/33191#issuecomment-768406687, which continues to report an error (it's a scenario without binding elements). Interestingly, #33191 is quite similar but that one has been resolved in 5.0, so perhaps my case falls under https://github.com/microsoft/TypeScript/issues/42529#issuecomment-769313907.

@JoostK maybe open up a new issue, then? I don't see why your code from https://github.com/microsoft/TypeScript/issues/33191#issuecomment-768406687 should be flagged as circular.

It is circular

What's the type of nextNode?
Depends on what the type of its initializer is
The initializer is currentNode.next. What's the type of the next property?
Depends on the possibly-seen inhabitants of the union. What are the types from the inbound control flows?
One inbound flow is from the assignment to currentNode from nextNode in the following line
What's the type of nextNode?
Hey that's the question we're asking

Depends on the possibly-seen inhabitants of the union. What are the types from the inbound control flows?
One inbound flow is from the assignment to currentNode from nextNode in the following line

What feels funny about this is that there's a declared type for next (Node | null). So couldn't this fall back to using that declared type, rather than raising a circularity error while trying to get a more precise one? Or would that open a different can of worms?

I recommend reading #45213 for a long discussion of the practicality of "falling back"

@danvk I'm glad that fix partially helped with this issue.

This issue is effectively a design limitation as @RyanCavanaugh describes here. The "fix" in #56753 is more of an accident because the logic in that PR suppresses circularity errors in manner that isn't consistent. We're reverting that logic in #59183 and the design limitation continues to exist.

authors: JoostK MichaelMitchell-at RyanCavanaugh ahejlsberg babakks danvk mprobst s0 tonivj5 vassudanagunta


text:
JSDoc: @inheritDoc disregards optionality of parameters from parent class method

TypeScript Version:  3.8.3

Search Terms: inheritDoc optionality jsdoc
Code
A conceptual example of JSDoc-annotated ES6 classes I'm generating d.ts definitions for
class Base {
  /**
   * @abstract
   * @param {Array<import("./Layer.js").default>} [opt_array] Array of layers (to be
   *     modified in place).
   * @return {Array<import("./Layer.js").default>} Array of layers.
   */
  getLayersArray(opt_array) {
    return abstract();
  }
}

class Derived {
  /**
   * @inheritDoc
   */
  getLayersArray(opt_array) {
      return [];
  }
}

Expected behavior:
TypeScript to transpile this to something resembling this
declare class Base {
    /**
     * @abstract
     * @param {Array<import("./Layer.js").default>} [opt_array] Array of layers (to be
     *     modified in place).
     * @return {Array<import("./Layer.js").default>} Array of layers.
     */
    getLayersArray(opt_array?: any[]): any[];
}
declare class Derived {
    /**
     * @inheritDoc
     */
    getLayersArray(opt_array?: any): any[];
}

Actual behavior:
The optionality specifier is lost on Derived.getLayersArray
declare class Base {
    /**
     * @abstract
     * @param {Array<import("./Layer.js").default>} [opt_array] Array of layers (to be
     *     modified in place).
     * @return {Array<import("./Layer.js").default>} Array of layers.
     */
    getLayersArray(opt_array?: any[]): any[];
}
declare class Derived {
    /**
     * @inheritDoc
     */
    getLayersArray(opt_array: any): any[];
}

Playground Link:
https://www.typescriptlang.org/play/?useJavaScript=true#code/MYGwhgzhAEBCkFNoG8CwAoa0D0AqXGW0u0AAmAEYQAuATmMNYViaQA5j0C2KAgrfQCeAHgCWXNgHta1ABQAiAHTYAMmEEJaigFYR5ASkUATBADMwAVxDUAfAF9oAbUltqAfU5CAutH5DokqbQ4Bq0MLLUktAUCMzERFhckkaipqIIRtCiAHbQbODACIZxrLQI1Ba0uch+6mIS0nJKquqaOnqGJuZWtg61ggFBIZoQiiXYzADm5WqhEP2yLu6e6voocdBlFVXQlDT0jLL6ANzMdhjn6BigkDAAIpqiAG4Z65g4+CVkOQAWj9R3STAcZTGatMILJYeASrN4JLBbSq5RxeU7vS52IA
Related Issues:

AFAIK we don't actually semantically recognize @inheritDoc.

source: gharchive/issue

authors: jumpinjackie weswigham

repo: microsoft/TypeScript

license_type: permissive

license_source: github-api


text:
Type '{ className: string; }' is not assignable to type 'IntrinsicAttributes & Props'. when using generics in component props.

TypeScript Version:  3.9.7

Search Terms:
Type  is not assignable to type 'IntrinsicAttributes & Props'.
Property does not exist on type 'IntrinsicAttributes & Props'
Code
This doesn't work.
type Props = {
  some?: string
}

export const SomeContainer = <PROPS extends Props, >({ some, ...rest }: PROPS): JSX.Element => {
  console.log(some)
  return (

  )
}

export const a = (
  <SomeContainer
    className='someClassName'
    // some='a' // <<<< HERE IS THE CHANGE
  />
)

This works
type Props = {
  some?: string
}

export const SomeContainer = <PROPS extends Props, >({ some, ...rest }: PROPS): JSX.Element => {
  console.log(some)
  return (

  )
}

export const a = (
  <SomeContainer
    className='someClassName'
    some='a'  // <<<< HERE IS THE CHANGE
  />
)

Expected behavior:
Both cases should not throw an error.
Actual behavior:
The first one throws:
JSX attribute) className: string
Type '{ className: string; }' is not assignable to type 'IntrinsicAttributes & Props'.
  Property 'className' does not exist on type 'IntrinsicAttributes & Props'.ts(2322)

We will have someone look into this

So, I looked at this for longer than I should have needed to before 🤦 ing and realizing nothing was wrong - className isn't a valid prop to pass because it's not mentioned in the constraint, and with no other valid props passed, gets flagged as excess (since the props being supplied share nothing in common with the weak generic constraint). className isn't a valid prop to pass because the only intrinsic property name is key (and in some versions ref) - other props, like className, are specific to HTML elements. If you wanna explicitly take HTML attributes (because you're forwarding to an HTML tag) you want to include React.HTMLAttributes in your constraint - eg, like so.

@weswigham  thanks for answer, I understand, i'll do that way,  but still wondering why such warning is not present when prop some is present. Shouldn't be this unified somehow?

We call types with exclusively optional properties "weak types", because they do very little to constrain a type, and consider assignments to them which have zero common properties between the source and target as likely an error (even though under other rules they would not be). Once the some property is present, that overlap exists, and we assume you know what you're doing with the other properties.

Hi, is there any guide on TypeScript typeset for props?
Currently I do as follow:
interface MyCompProps {
	someAttr: number
}

I then want to use className and aria, but listing them manually is incredibly cumbersome. I look around and found nothing until I hit this issue. Now it's clear for me: interface MyCompProps extends React.HTMLAttributes<any>, though I still don't fully understand it as I don't have an extensive guide on this matter.

Help me please. I have this issue
Type '{ setEditTodo: Dispatch<SetStateAction<string | null>>; }' is not assignable to type 'IntrinsicAttributes & ToDoState'.
Property 'setEditTodo' does not exist on type 'IntrinsicAttributes & ToDoState'.
"use client";
import React, { useState } from "react";
import { BsEmojiSmile } from "react-icons/bs";
import { AiOutlinePlus } from "react-icons/ai";
import Picker from "@emoji-mart/react";
import data from "@emoji-mart/data";
import { TodoItem } from "./TodoItem";
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
import { addTodo } from "../../redux/slice/todoSlice";
// interface TodoSetProps {
//   setEditTodo: React.Dispatch<React.SetStateAction<string | null>>;
// }
interface TodoItemProps {
id: number;
text: string;
date: Date;
completed: boolean;
setEditTodo: React.Dispatch<React.SetStateAction<string | null>>;
}
interface ToDoState {
todoList: TodoItemProps[];
}
const Todo: React.FC = () => {
const [showEmoji, setShowEmoji] = useState(false);
const [text, setText] = useState("");
const [editTodo, setEditTodo] = useState<string | null>(null);
const dispatch = useAppDispatch();
// add emoji
const addEmoji = (e: any) => {
const sym = e.unified.split("_");
const codeArray: any = [];
sym.forEach((el: any) => codeArray.push("0x" + el));
let emoji = String.fromCodePoint(...codeArray);
setText(text + emoji);
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
dispatch(addTodo({
id: Math.floor(Math.random() * 100000),
text,
date: new Date().toISOString(),
completed: false,
}))
}
return (

tailwind todo list

  {/* todo input  */}
  <form
    onSubmit={handleSubmit}
    className="flex items-start gap-2 pt-2rem">

      <textarea
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="write your text"
        className="w-full bg-transparent outline-none resize-none text-sm"
        cols={30}
        rows={2}></textarea>

       setShowEmoji(!showEmoji)}
        className="cursor-pointer hover:text-slate-300">
        <BsEmojiSmile />

      {showEmoji && (

          <Picker
            data={data}
            emojiSize={20}
            emojiButtonSize={28}
            onEmojiSelect={addEmoji}
            maxFrequentRows={0}
          />

      )}

    <button
      className="flex items-center capitalize gap-2 bg-yellow-200 text-black py-1.5
        px-3 rounded-sm hover:bg-yellow-100">
      <AiOutlinePlus />
      {editTodo ? "update" : "add"}
    </button>
  </form>

  {/* print the todo lists  */}

    <TodoItem setEditTodo={setEditTodo} />

);
};
export { Todo }
"use client";
import {
AiTwotoneDelete,
AiTwotoneEdit,
AiOutlineCheckCircle,
} from "react-icons/ai";
import { FaTimes } from "react-icons/fa";
import React, { useState } from "react";
import moment from "moment/moment";
import Layer from "./Layer";
// interface TodoSetProps {
//   setEditTodo: React.Dispatch<React.SetStateAction<string | null>>;
// }
interface TodoItemProps {
id: number;
text: string;
date: Date;
completed: boolean;
setEditTodo: React.Dispatch<React.SetStateAction<string | null>>;
}
interface ToDoState {
todoList: TodoItemProps[];
}
const TodoItem: React.FC = () => {
const [showText, setShowText] = useState(false);
const [showFullText, setShowFullText] = useState("");
const fullText = (id: number) => {
const todoText = todo.find((todo) => todo.id === id);
if (todoText) {
setShowFullText(todoText.text);
setShowText(true);
}
};
const todo = [
{
id: 1,
text: "Hello world",
date: new Date(),
completed: false,
},
{
id: 2,
text: "Hello world",
date: new Date(),
completed: false,
},
];
return (

{todo.map((todo, i) => (

{moment(todo.date).fromNow()}

          {todo.text.substring(0, 36)}
          {todo.text.length > 36 && (
            <button
              onClick={() => fullText(todo.id)}
              className="text-red-400 text-xs hover:text-red-600">
              ...more
            </button>
          )}

            <AiTwotoneDelete />

            <AiTwotoneEdit />

            <AiOutlineCheckCircle />

      {showText && (

           setShowText(false)}
            className="absolute top-10 right-10 text-xl cursor-pointer hover:text-slate-500">
            <FaTimes />

            <Layer text={showFullText} />

      )}

  ))}

);
};
export { TodoItem }

authors: Inna-Mykytiuk RyanCavanaugh nvmnghia rostislav-simonik rostislav-simonik-plc weswigham


text:
ReturnType not being evaluated when used in function definition generics alias

Scenario:
Given an indexed object of functions that return different value types, generate a new object with the same indexes and the return value of the functions.
const given = {
  foo: () => 1,
  bar: () => 'milka',
};

const generatedResult = {
  foo: 1,
  bar: 'milka',
};

Failing example:
TypeScript is not re-evaluating the Types when calling the function with predictable values:

It can predict the functions and their return types, but it is not evaluating ReturnType<...>
Workaround example:
The proper types are correctly inferred when using an anonymous type directly in the return type of the function:

This workaround is not desired given the need for using the Type definition inside the body of the function.
TypeScript Version:  4.0.3

Search Terms:

ReturnType
Generics

Code
function extract<
  P extends string,
  M extends Record<P, () => any>,
  Ret extends {
    [K in P]: ReturnType<M[K]>;
  }
>(_map: M): Ret {
  return <Ret>{};
}

const { foo, bar } = extract({
  foo: () => 1,
  bar: () => 'bar',
});

Expected behavior:
Variable foo should be of type number
Variable bar should be of type string
Actual behavior:
All variables are of type any
Playground Link:
Playground Link or a CodeSandbox Link - Both with the same behavior.

Why do you need so many extra type params?
This is more than enough,
function extract3<M extends Record<string, () => any>> (_map : M) : {
  [k in keyof M] : ReturnType<M[k]>
} {
  return {} as any;
}

Also, try this instead,
function extract<
  P extends keyof M,
  M extends Record<string, () => any>,
  Ret extends {
    [K in P]: ReturnType<M[K]>;
  }
>(_map: M): Ret {
  return {} as Ret;
}

If we change your example a little, you'll see that your initial extract doesn't really make sense.

Playground

@AnyhowStep You might have got it wrong.
In a strict environment with enforced types, and no-unsafe-any enabled, those examples are not valid.
Also, your example will only return string types, while every key has its own type.
In my case foo is a number, bar is a string.
Your example both are strings, what is not correct.
Also, in a strict environment, you should not typecast something to any just to return it.

Also, in a strict environment, you should not typecast something to any just to return it.

That is just done to focus on the types, instead of having to create the implementation of the function.

I don't see the reason for the complexity. What you want can trivially be written as:
type DesiredReturn<T extends Record<any, () => any>> = { [P in keyof T]: ReturnType<T[P]> }

// Type is { foo: number; bar: string; }
type ParameterReturn = DesiredReturn<Parameter>;

function extract<T extends Record<any, () => any>>(parameter: T): DesiredReturn<T> { /* implementation be here */ }

const { foo, bar } = extract({ foo: () => 0, bar: () => '' });

I'm aware of alternatives, but none of the already suggested ones solves the problem or prove that it is not an issue.
Lets see a more complex example:
const randomFn = <T>(): T | null => null;

export default function makeSelector<T>(context: T) {
  return <
    Keys extends keyof Selectors,
    Selectors extends Record<string, (context: T) => unknown>,
    TRet extends { [K in Keys]: ReturnType<Selectors[K]> }
  >(
    selectors: Selectors,
  ): TRet => { // HERE if I replace the named type TRet with { [K in Keys]: ReturnType<Selectors[K]> } it magically works 🤷🏻♂
    // actual implementation
    // data fetching and parsing and then pass it to another fn
    const ret = randomFn<TRet>();
    return ret;
  };
}

const selector = makeSelector({ unrelated: true, nothingSpecial: false });

const { foo, bar } = selector({ foo: () => 0, bar: () => '' });

As explained in the issue description, if I delete the TRet definition and just put { [K in Keys]: ReturnType<Selectors[K]> } as the return type, it magically works.
another playground with a working example.

Your code is failing because TypeScript can't infer the type of TRet from anything. It only knows what it should extend, but it doesn't know what the type actually looks like.
That's why it works if you remove the type parameter and actually provide the return type. This is working as intended.

It is able to figure it out.
If you hover your mouse at selector({ foo: () => 0, bar: () => '' }); you will see all the parameters, functions, Keys and return types are there.

Everything is there, except for the TRet, that depends on ReturnType.

It is able to figure it out.

Not fully, that's why you get the any. It can't figure out the type of the properties. It knows what the types should extend, but not what the types are. If you provide the type arguments yourself (so no inference is necessary) you get the desired result. With your initial example:
function extract<
  P extends string,
  M extends Record<P, () => any>,
  Ret extends {
    [K in P]: ReturnType<M[K]>;
  }
>(_map: M): Ret {
  return <Ret>{};
}

const { foo, bar } = extract<
  'foo' | 'bar',
  { foo: () => number, bar: () => string },
  { foo: number, bar: string }
>({
  foo: () => 1,
  bar: () => 'bar',
});

Look at the code of extract. Based on what information would the compiler be able to infer the exact type of Ret? There's simply not enough information available.

But then, why does it work if I remove the named TRet generic and just put the anonymous:
{ [K in Keys]: ReturnType<Selectors[K]> } as the return of the function?
Why does the named one fail while the anonymous work?

Because then there is no type to infer. The compiler knows the exact type. The compiler doesn't need to figure out "what is the type, and does it extend this other type".

Why does the named one fail while the anonymous work?

You're assuming TRet just means "I have a named type", but that's not the case. You're having a generic type argument, so the method can accept different types for TRet (they just must extend a specific type). Unless explicity provided (see my example) it must be inferred by the compiler.

I might be underestimating it,
But if I look again at the screenshot of the Hover over the extract function.
Every single type is there, the properties, the functions, and the return type of the given functions.
I'm still not following why only the part where ReturnType is used is unable to infer the type.
The compiler is literally showing every single piece of information in the screenshot.

Every single type is there, the properties, the functions, and the return type of the given functions.

The first two type arguments can easily be inferred from your input argument (both P and M are used as part of _map). But where should the third type argument be inferred from? The third type argument must be inferred from the value you return within your function, and there's not enough information available for this.

I'm still not following why only the part where ReturnType is used is unable to infer the type.

It's unrelated to ReturnType. Remove it, just use M[K] and you have the same issue.

It's unrelated to ReturnType. Remove it, just use M[K] and you have the same issue.
I see your point now.

But how is it different, if we move the definition from the generic argument to the return type?

Because then there is no type inference necessary anymore. The compiler doesn't need to figure out what Ret ist, it knows it's this specific type.
The difference is:

With the generic return type Ret: Compiler needs to figure out, what is Ret and does it extend { [K in P]: M[K] }?
With the non-generic return type { [K in P]: M[K] }: Compiler doesn't need to figure out the return type. It's { [K in P]: M[K] }.

Nice, thanks for the patience and the extremely detailed explanation.
What we do now?
Is it a feature-request then? instead of a bug?
Or, ~please god no~, is it a Wont-do?
because it is extremely useful to have it inside a Closure and being able to pass this generic argument deeper.

It sounds to me that you don't actually want a generic type, but you just want to reference your rather large type using a local type alias. For this there's #40780 / #30979. But there hasn't been any progress, and likely there won't be in any foreseeable future.

Looking at your screenshots, both are strings, what is not correct.
{ [x: string]: string; } // from your screenshot, not the actual real type.

I know. I'm saying that you've structured your types in a way that doesn't make sense.
I'm showing you examples of why your attempts do not make sense.

Having type parameters that cannot be inferred/constrained from the actual function arguments is also actually an anti-pattern.
Assume your desired type parameter Ret actually works. We have this problem,
function extract<
  M extends Record<string, () => any>,
  Ret extends {
    foo : number,
    bar : string,
  }
> (_map : M) : Ret {
  return {} as any;
}

const obj = {
  foo: () => 1,
  bar: () => 'bar',
} as const
const { foo, bar } = extract<
  typeof obj,
  {
    foo : 32,
    bar : "lol",
  }
>(obj);

Playground

Notice that even thought obj returns 1, and "bar", the user can mess things up by setting Ret to be a subtype of { foo : number, bar : string }.
You pointed out that one "should not typecast something to any just to return it".
However, your Ret type parameter is exactly that.
It is a "hidden" cast to practically any data type one wants.

Doesn't seem like there's a bug here. Thanks for the good discussion everyone.

authors: AnyhowStep MartinJohns RyanCavanaugh carlos-algms


text:
String literal type is always widened when used as a generic type parameter

TypeScript Version:  v4.2.0-dev.20201130
Search Terms: widening type parameter
Code:
function fn<T extends 'foo' | 'bar'>(a: T, b: T) {}
fn('foo', 'bar');

Expected behavior: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.. Since 'foo' and 'bar' are different types, it shouldn't be possible for the same type parameter to allow both of them.
Actual behavior: no error, since the arguments' types are widened.
This definitely seems like reasonable behavior without an explicit "extends" clause (this was brought up in #6167):
function fn<T>(a: T, b: T) {}
fn('foo', 'bar'); // I *want* this to resolve to string! only args like (10, 'foo') should break

But this behavior is harder to justify in my first example, since I'm treating the string literal types like enum values; I want them to behave independently as their own types, not widen and act like the same type when they're being matched to the T type parameter.
It might not be so easy to tell the programmer's intention in this case, but it should be clearer here:
function fn2<T extends 'foo' | 'bar'>(a: T, b: T) {}
const foo: 'foo' = 'foo'; // I think the type annotation is redundant here because it's a const declaration
const bar: 'bar' = 'bar';
fn2(foo, bar);

This still doesn't error, which tells me the type is still widening to 'foo' | 'bar' even though the arguments are very explicitly typed as 'foo' and 'bar'. The widening only seems to happen when the arguments are actually different. When I hover over the function call in VS Code (not sure what that view is called), I see two different evaluated type definitions depending on the function call:

If I hover over fn2(foo, foo), I get function fn2<"foo">(a: "foo", b: "foo"): void.
If I hover over fn2(foo, bar), I get function fn2<"foo" | "bar">(a: "foo" | "bar", b: "foo" | "bar"): void.

This seems to indicate that the type system is explicitly making a widening decision when it "notices" that the literal type doesn't fit, which I don't really want it to do.
#6196 seems to be the closest anyone got to addressing the concerns raised in #6167. This seems to have been enough to close out #6167, but unfortunately it only strictifies conditional logic, not this type parameter spookiness.
Here's another (slightly closer to real-world) example, similar to what I was building when I came across this issue. In this example, it's trickier (i.e. not constant-time) to determine the second argument's type based on the first argument at runtime (where, obviously, in my first example, there's no reason to write a function that takes in the exact same string two times):
type Key = "foo" | "bar";
type Haystack<T> = Array<number | T>;

function fn<T extends Key>(a: T, b: Haystack<T>) {}

fn("foo", [1, 2, 3, 4, "foo"]);
fn("foo", [1, 2, 3, 4, "bar"]); // should error
fn("bar", [1, 2, 3, 4, "foo"]); // should error
fn("bar", [1, 2, 3, 4, "bar"]);

Workarounds:
One option is to call the function with an explicitly-bound T:
function fn<T extends 'foo' | 'bar'>(a: T, b: T) {}
fn<'foo'>('foo', 'bar'); // Argument of type '"bar"' is not assignable to parameter of type '"foo"'.

This also works with typeof, which (as far as I can tell) should be available in every case where the type-checker would be able to determine that there's an error anyway:
function fn<T extends 'foo' | 'bar'>(a: T, b: T) {}
const foo = 'foo';
const bar = 'bar';
fn<typeof foo>(foo, bar); // Argument of type '"bar"' is not assignable to parameter of type '"foo"'.

This doesn't feel like a general-purpose solution, though, because the T parameter might not be so easily accessible:
type Key = "foo" | "bar";
type Haystack<T> = Array<number | T>;

function fn<T extends Key>(a: Haystack<T>, b: Haystack<T>) {}

fn([1, 2, 3, 4, 'foo'], [5, 6, 7, 8, 'bar']);
// fn<typeof ????>(...)
// it's trickier (but still possible) to come up with an example like this that doesn't use array literals.

Here's another workaround I found, and honestly I don't understand why this works:
function fn<T extends 'foo' | 'bar', E extends T>(a: T, b: E) {}
fn('foo', 'bar'); // Argument of type '"bar"' is not assignable to parameter of type '"foo"'.

The fact that introducing a second type parameter that's identical to the first one causes the type not to be widened is really surprising to me. Even if the opinion of TS is that my initial code example shouldn't result in an error, it seems like a bug that this snippet behaves differently.
Playground Link:
https://www.typescriptlang.org/play?ts=4.2.0-dev.20201130#code/GYVwdgxgLglg9mABMMAeAKogpgDylsAEwGdEByYOOMxAH3ICMBDAJzID4AKJgLkXQA0iBn3QBKRAG8AvgCgUnClTJCyzNmIDcQA
Related Issues:
#6167: this issue is described in the "Widening" section. this issue was closed by a few PRs that address related behavior, but which don't actually fix this particular problem.
#5300, #5517
#6196, which seems to be the closest anyone got to addressing this

Related issues:
#27808: extends_oneof constraint: Right now, generic type parameters constrained to a union type are allowed to be specified with any subset of the union, including the full union.  Saying <T extends "foo" | "bar"> means that the compiler should feel free to specify T as "foo" | "bar" if it wants to.  There's currently no way to say "T can be "foo" or "bar" but not "foo" | "bar".  The proposal here would allow something like <T extends_oneof "foo" | "bar"> to mean "T should be assignable to exactly one member of the union "foo" | "bar", which is what you want.

#14829: non-inferential type parameter usage:  It would be nice if you could tell the compiler that you don't want it to infer T from both the a and b parameters.  Instead, you want it to infer T from, say, just a... and then check that such an inference works for b.  Or put another way: you want the T in b: T to be "non-inferential".  If you could mark such a use like NoInfer<T> instead of just T, then you'd get the desired behavior:
function fn<T extends 'foo' | 'bar'>(a: T, b: NoInfer<T>) { }
fn('foo', 'bar'); // error!
// -----> ~~~~~
// Argument of type '"bar"' is not assignable to parameter of type '"foo"'

There's no direct support in the language for NoInfer<T>, but the linked issue does provide some implementations of it that work well enough in some circumstances.  This is the one I tend to use:
type NoInfer<T> = [T][T extends any ? 0 : never];

which makes the above work.
Playground link to code

Thanks for the pointers!
The reason I attributed this issue to literal widening is that when I tried this with other types, I saw the behavior I was expecting:
function fn<T extends string | number>(a: T, b: T) { }

// function fn<"foo" | "bar">(a: "foo" | "bar", b: "foo" | "bar"): void
fn('foo', 'bar'); // no error

// function fn<"foo">(a: "foo", b: "foo"): void
fn('foo', 1); // Argument of type '1' is not assignable to parameter of type '"foo"'.

// function fn<1 | 2>(a: 1 | 2, b: 1 | 2): void
fn(1, 2); // no error

Playground link
Do you know why this results in an error, even though extends behaves as you pointed out?

@jcalz pointed to the issues that I would have; this is very much intentional.
Just to help with search terms, zero widening whatsoever occurs in this example. The same behavior is seen when the arguments are nonwidening literal types, for example:
function fn<T >(a: T, b: T) {}
declare const f: "foo", b: "bar";
fn(f, b);

What's happening is that generic inference is allowed to form literal unions of a common primitive type when faced with multiple inference candidates that don't share a common supertype. This is broadly desired behavior, especially in the unconstrained case.
There's a strong consistency argument that adding an extends U constraint to an existing generic function should not cause extant calls to fail if they would have succeeded with an explicit U type argument, since that on its face makes no sense. In other words
// If this succeeds
function fn1<T>(a: T, b: T): void;
fn1(x, y);
// and this succeeds
fn1<U>(x, y);
// it would unjustifiable for this to fail
function fn2<T extends U>(a: T, b: T): void;
fn2(x, y);

@RyanCavanaugh Thanks for the insight! Your logic makes sense, and indeed I was mistaking this "common primitive type" behavior for widening (because to me, it feels like a pretty similar case to where widening kicks in; where the two unioned types don't have a common supertype, they're only allowed to share that type parameter because they have the same primitive type. As far as I can tell, that's the same behavior as if the type parameter were simply interpreted as string in this case). I'm still not sure I understand how this example is different from the "Widening" section in #6167, though.
It's also interesting to me that this behavior seems not to survive one "hop" across type parameters, like in my last 'workaround' example:
function fn<T extends 'a' | 'b', U extends T>(a: T, b: U) {}
fn('a', 'b'); // fails

Is there a theoretical reason why this should be different from the simpler case with just one type parameter, or is it just a quirk of  TypeScript's implementation of this generic inference? It does feel weird to me to do this in my own code, since it's hard (for me, at least) to understand why this 'hack' does what it does.
Thanks again for engaging.

Type parameter inference occurs for all type parameters "simultaneously", rather than going through an N-round unification process that would create a backpropagation effect from U to T, so once T is fixed to "a" and U is fixed to "b" there's no further changes to the inference result.

I see! I was thinking that the stuff inside the angled brackets somehow gets "resolved" first, not that it starts from the arguments, binds the types, and then checks against the type parameters. It makes more sense when I tihnk about it in that direction.
Thanks! Closing out the issue now :)

authors: RyanCavanaugh SyntaxBlitz jcalz


text:
Can't assign to conditional generic within generic

Hi I was trying to do something much more complicated than this with conditionals without success, I was reducing the issue down and down and I found this, which I find a bit weird, I was hoping someone might be able to enlighten me of a work around?

TypeScript Version:  v4.1.2

Search Terms:
assign to conditional generic
Code
type Param<T> = T extends undefined ? {
    first: string,
} : {
    first: string,
}
function run<T>(param: T) {
    const p: Param<T> = {
        first: 'hi'
    }
    return p;
}

Expected behavior:
No type error
Actual behavior:
type error
Playground Link:
link here
Related Issues:
I couldn't find any, sorry if this is a well known problem / duplicate!

Duplicate of #26933. Search terms used: assign conditional

authors: MartinJohns ayroblu


text:
Incorrect Report that an Object may be null

Bug Report

🔎 Search Terms

Object is possibly 'null'
undefined

🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about unexpected warnings about possible 'null's and 'undefined's.
I tried versions 3.3.3333 and 4.3.0-beta, though I did not try any in the middle.
⏯ Playground Link
Playground link with relevant code
💻 Code

const refs: {current: {value: number} | null}[] = [{current: { value: 2}}];

if (refs.every((ref) => ref.current != null)) {
    refs[0].current.value = 1;
}

🙁 Actual behavior
"Object is possibly 'null'" warning on refs[0].current
🙂 Expected behavior
No warnings, as they cannot be null since the refs.every(...) is checking that.

Similar to https://github.com/microsoft/TypeScript/issues/16069, maybe https://github.com/microsoft/TypeScript/issues/18562.
One of the problems with this is that if something mutates the underlying array, your assumptions would be invalidated.

I think we can call it a duplicate of / encompassed by https://github.com/microsoft/TypeScript/issues/38390

Yes we can!


text:
Inconsistent boolean literal types

🕗 Version & Regression Information
This is the behavior in every version I tried.
⏯ Playground Link
Playground link with relevant code
💻 Code
type Box<T> = {
    get: () => T,
    set: (value: T) => void
}

declare function box<T>(value: T): Box<T>;

const bn1 = box(0);  // Box<number>
const bn2: Box<number> = box(0);  // Ok

const bb1 = box(false);  // Box<boolean>
const bb2: Box<boolean> = box(false);  // Error, box<false> not assignable to Box<boolean>

🙁 Actual behavior
Error on bb2 is surprising and inconsistent with lack of error on bn2.
🙂 Expected behavior
Expected the box(false) expression to have type Box<boolean> for both bb1 and bb2.

Related: #48150

The issue here is that when a boolean literal (false or true) is contextually typed by type boolean, we don't widen the type of the literal to boolean. This is inconsistent with our behavior for string, number and bigint literals which are widened when their contextual type is string, number or bigint, respectively. The difference comes from the fact that boolean is just an alias for the union type false | true, whereas string, number, and bigint aren't (infinite) unions of literals, but rather distinct primitive types.
This issue was discussed in #48150 and before that here. It definitely seems odd and inconsistent. We'd be better off considering the contextual type boolean akin to string, number, and bigint for purposes of widening literals. I know we tried that in the past and one issue was a boolean contextual type arising from separate false and true types as discriminants. For example:
let x: { kind: false, x: number } | { kind: true, x: string } = { kind: false, x: 42 };

Here, at least in the past, the kind property in the object literal would have the contextual type boolean (the union of false and true). However, these days we discriminate the contextual type by discriminant properties in the object literal, thus removing the { kind: true, x: string } variant, and therefore the contextual type is just false. And thus we wouldn't widen.
I'm going to put up a PR to see what the effects are.

authors: MartinJohns ahejlsberg


text:
in operator typeguard precision loss

Bug Report
🔎 Search Terms
🕗 Version & Regression Information
v4.9.0 v4.9.1
⏯ Playground Link
Playground link with relevant code
💻 Code
function addressOrThrow(value: unknown) {
  if (typeof value !== "object" || value == null) throw new TypeError();

  if (!("street" in value) || typeof value.street !== "string")
    throw new TypeError();

  if (!("houseNumber" in value) || typeof value.houseNumber !== "number")
    throw new TypeError();

  return value;
}

function addressOrThrowTG(value: unknown): value is Address {
  addressOrThrow(value);
  return true;
}

function personOrThrow(value: unknown) {
  if (typeof value !== "object" || value == null) throw new TypeError();

  if (!("firstName" in value) || typeof value.firstName !== "string")
    throw new TypeError();

  if (!("lastName" in value) || typeof value.lastName !== "string")
    throw new TypeError();

  if ("middleName" in value && typeof value.middleName !== "string")
    throw new TypeError();

  if (!("addresses" in value) || !Array.isArray(value.addresses))
    throw new TypeError();

  if (!value.addresses.every(addressOrThrowTG))
    throw new TypeError();

  return value;
}

type Address = ReturnType<typeof addressOrThrow>;

type Person = ReturnType<typeof personOrThrow>;

🙁 Actual behavior
type Address = object & Record<"street", unknown> & Record<"houseNumber", unknown>
type Person = object & Record<"firstName", unknown> & Record<"lastName", unknown> & Record<"addresses", unknown>
🙂 Expected behavior
type Address = object & Record<"street", string> & Record<"houseNumber", number>
type Person = object & Record<"firstName", string> & Partial<Record<"middleName", string>> & Record<"lastName", string> & Record<"addresses", Address[]>

@ahejlsberg any easy way to make this happen?

I would be glad to help with this issue as well, along with #51338.

Also just ran into this. Here is a playground reproducing the issue.
The above errors in version 4.9.3 but no error in 4.8.4

authors: RyanCavanaugh arahansen kamalesh0406 santa-trout


text:
infer Self

Suggestion
🔍 Search Terms
Automatic generic parameter
Generic type self reference
Generic Self keyword
Infer Self
Exclude from any
✅ Viability Checklist
My suggestion meets these guidelines:
[x] (I think) This wouldn't be a breaking change in existing TypeScript/JavaScript code
[x] (if done right) This wouldn't change the runtime behavior of existing JavaScript code
[x] This could be implemented without emitting different JS based on the types of the expressions
[x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
[x] This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
Instead of writing
type DoesTheThing<T> = T extends Something<T> ? T : never

and then
const something = aLongVariableName as DoesTheThing<typeof aLongVariableName>

it would be nice to have a way to infer the generic type in these instances.
Like this:
type DoesTheThing = infer Self extends Something<Self> ? Self : never

which could then be used like this:
const something: DoesTheThing = aLongVariableName

With the risk of being off-topic another thing that would be nice, albeit not as nice as the above, is the ability to Exclude from any.
type NotAString = Exclude<any, string> // anything that is not a string

I have three variations of my main suggestion, infer Self, that carry varying risks:

(least risk) what I've already mentioned. infer Self has to be in the beginning of the type definition.
(low or no risk) You don't have to write Self but can write any name as long as it's in the start of the expression.
(most risky) You have to write Self (or another keyword) but you can use the keyword in other places as well.

📃 Motivating Example
const aString = "some string"
const aFunction = (test: string) => "string"

// This is how we have to do it now
export type NotFunction<T> = Exclude<T, (...args: any) => any>

const old1 = aString as NotFunction<typeof aString>
//    ^123
const old2 = aFunction as NotFunction<typeof aFunction>
//    ^never

// Least risky change
export type NiceNotFunction = infer Self extends Exclude<Self, (...args: any) => any> ? Self : never

// Maybe more risky (?)
export type AlsoNiceNotFunction = infer ThisIsAlsoSelf extends Exclude<ThisIsAlsoSelf, (...args: any) => any> ? Self : never

const new1: NiceNotFunction = aString
// ^ Should extend string but is any currently

const new2: NiceNotFunction = aFunction
// ^ Should be never but is any currently

// Most risky/difficult change.
// InferSelf would be overrideable so that it doesn't mess up old codebases.
// It could also be a different keyword that would be a syntax error before this change,
// for example by including a space.
export type NicerNotFunction = Exclude<InferSelf, (...args: any) => any>

const new3: NicerNotFunction = aString
// ^ Should extend string but is any currently

const new4: NicerNotFunction = aFunction
// ^ Should be never but is any currently

💻 Use Cases
Google jsonable typescript to get lots of examples, the top result being this. There's also been another typescript suggestion to add JSON as a default type.
In the article, the author suggests doing this:
type JSONValue =
    | string
    | number
    | boolean
    | JSONObject
    | JSONArray;

interface JSONObject {
    [x: string]: JSONValue;
}

interface JSONArray extends Array<JSONValue> { }

This works but it's a bit verbose for what I wanted. I also wanted to allow undefined and null, and in that case basically anything can be JSON serialized except for functions and symbols if I'm not mistaken.
So I went on to google on how to make a NotFunction type. This was the top result, and they suggest doing this:
type NotFunction<T> = T extends Function ? never : T;

Which brings me to what I've already said.

I have a hard time figuring out from the examples what you're trying to do. Are you looking for the satisfies operator, or negated types?
Like, for this example:
type DoesTheThing<T> = T extends Something ? T : never
const something = aLongVariableName as DoesTheThing<typeof aLongVariableName>
type DoesTheThing = infer Self extends Something ? Self : never
const something: DoesTheThing = aLongVariableName

You could have written this?
const something: Something = aLongVariableName

I have a hard time figuring out from the examples what you're trying to do. Are you looking for the satisfies operator, or negated types?
Like, for this example:
type DoesTheThing<T> = T extends Something ? T : never
const something = aLongVariableName as DoesTheThing<typeof aLongVariableName>
type DoesTheThing = infer Self extends Something ? Self : never
const something: DoesTheThing = aLongVariableName

You could have written this?
const something: Something = aLongVariableName

Sorry I made a mistake here. I meant:
T extends Something<T> ? T : never`

So that's
const something = aLongVariableName satisfies DoesTheThing<unknown>;

or
interface Something<T> {
  x: T
}
const aLongVariableName = { x: 3 } satisfies Something<unknown>;

The feature request sounds a lot like what has been PRed here

@Andarist That does indeed seem very similar, apologies for that. When scrolling through that issue I thought it was a different thing because of the explicit generic parameter. For example: type CaseInsensitive<T extends string> = self extends string.
I should've looked more carefully. With that being said I did come up with some different variations of the same general idea which might be useful. I've posted a comment on that PR.

authors: Andarist RyanCavanaugh henrikeliq


text:
Quick fix module imports suggestions does not work with newly installed packages.

Bug Report
Quick fix module imports suggestion does not work with newly installed packages.
The TS Server does not seem to scan the node_modules package that have been newly installed, even after restarting TS Server, or after restarting Visual Studio Code.
🔎 Search Terms
typescript restart ts server module imports not found
🕗 Version & Regression Information
"typescript": "~5.1.3"
"tslib": "^2.5.3",
Visual Studio Code 1.79.2
node 18.16.0

🙁 Actual behavior
Create a new Angular project, last version

ng new Toto
cd Toto
code .
from the terminal:
npm install @angular/material --save
open src/app/app.module.ts
in imports, add MatButtonModule, and save.
type F1, then > typescript restart TS Server

The issue is the import of MatButtonModule is not proposed as a quick fix.

But if I remove an angular native modules, for example import { CommonModule } from '@angular/common'; then it works for that import:

If I add the import manually, then the module is found in node_module, and there is no more issue

🙂 Expected behavior
import of MatButtonModule should be proposed as a Quick fix:

Auto-import can only offer suggestions from modules that are already "known", i.e. part of your program already. Installing the modules alone isn't always going to be sufficient to get them into that known set. You'll have to import them at least once the old-fashioned way, after which point auto-import should be surfacing all identifiers from the imported module.

authors: Anthony-Breneliere RyanCavanaugh


text:
[TS 5.4.0-beta] Tuple type members being perserved

🔎 Search Terms
spread tuple type narrowing
🕗 Version & Regression Information

This changed between versions 5.3.3 and 5.4.0-beta
This changed in 5.4.0-dev.20240120

⏯ Playground Link
https://www.typescriptlang.org/play?ts=5.4.0-beta#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwHMQMAVAHhID4AKASgC54SBuAKFYAUYcBbLAZxAA6KBAjUA2kVJl+GGFlQEatADTwhm6eSioAnioC6tVvDNCMACxCpq1OP2QQMteAF5K8AN6mzfswD0AfAAegD8vv5geHLw1lDA7vAOThgSAAyGzP5+QfAArEIAzIy6euqFACyMcgpKkTnweeENZtGosRhQWBBJKc5C-BBYYCDUAIy02XmFRfBlFULV8GgA1qg4AO6oEoat-s0RjV098PxQ2PyIWCD8Z-KKBLvZB8FkALTv8Kggm-AgMG4MHgigKS0iAF8pqwgA
💻 Code
declare function getT<T>(): T;

Promise.all([getT<string>(), ...getT<any>()])
   .then((result) => {
        // ^?
      const head = result[0];       // 5.3: any, 5.4: string
         // ^?
      const tail = result.slice(1); // 5.3 any, 5.4: unknown[]
         // ^?
      tail satisfies string[];     // <-- new error in 5.4
   });

Additional information about the issue
More of a 'change report' than a 'bug report', I don't think this was part of the 5.4 beta announcement.

This can be bisected to: https://github.com/microsoft/TypeScript/pull/57031 and it's a bug.
When hovering over all we can see this:
(method) PromiseConstructor.all<[string, ...any[]]>(values: [string, ...any[]]): Promise<[string, ...unknown[]]> (+1 overload)

So how [string, ...any[]] was converted into [string, ...unknown[]] here? The reason is that now instantiateMappedTupleType has this ?? unknownType fallback when computing newElementTypes.
But it's not consistent with how mapped types continue to work today:
type Identity<T> = {
   [K in keyof T]: T[K]
}

type Result = Identity<[string, ...any[]]>
// ^? type Result: [string, ...any[]]

So the problem is that what we see in the original repro is actually not a true any but rather an errorType. And if we play around with it we can see the change in the behavior:
type Identity<T> = {
   [K in keyof T]: T[K]
}

type ErrorType = {}['prop']

type Result = Identity<[string, ...ErrorType[]]>
//   ^? 5.3: any (displayed as `any` but it's an `errorType`) 5.4: [string, ...unknown[]]

The PR to which this has been bisected improves the situation (the output should be a tuple and not an any/errorType) but accidentally maps the thing to [string, ...unknown[]].
Why the errorType has crawled into all of this though? Well, I already have a fix for this 😉 : https://github.com/microsoft/TypeScript/pull/57116

authors: Andarist acutmore


text:
tsconfig.json option to ignore error TS2307 (or any specific error)

🔍 Search Terms

TS2307
Ignoring specific error

✅ Viability Checklist

[X] This wouldn't be a breaking change in existing TypeScript/JavaScript code
[X] This wouldn't change the runtime behavior of existing JavaScript code
[X] This could be implemented without emitting different JS based on the types of the expressions
[X] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
[X] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
[X] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

⭐ Suggestion
In our project we're using some convenience babel magic to add "virtual" packages which inject data into the client application. E.g.
import staticURL from 'indico-url:plugin_vc_zoom.static';

(fetches a URL from the backend's blueprint map)
This is obviously not appreciated by TypeScript, although it's not an issue in the end because we transpile it using Babel. On the other hand, VS Code does complain about it because TS does. Having the VS Code integration is useful and we'd like to continue using it and mute this particular error.
Right now the only option we have is to do something like:
// @ts-expect-error URL import
import staticURL from 'indico-url:plugin_vc_zoom.static';

... which is not great, especially if you end up in a file which has several of those.
Hence, it would be very useful if we could have an option to mute a particular error, or at least something which lets us tell Typescript that we don't want to see errors about unresolved modules (we get those from ESLint anyway).
I found this old discussion, from which there was no conclusion. Maybe there's something new?
📃 Motivating Example
"You're now able to silence particular errors, which is especially useful if you are already using a dedicated linting tool such as ESLint and want to have full control over which errors you see."
💻 Use Cases

What do you want to use this for?

Development in a large project where we are using also Babel + ESLint

What shortcomings exist with current approaches?

Typescript is used both as a transpilation and static checking tool (by VSCode). It obviously complains about missing modules, which is good, and that would be fine if we were not depending on it also for VS Code "linting". I have no way to silence particular false positives unless I do so line by line.

What workarounds are you using in the meantime?

Silencing errors line by line with // @ts-expect-error, which is far from ideal.

Why not just tell TypeScript that these are valid module imports, instead of silencing the error?
Create a .d.ts file and add this line: declare module "indico-url:*";

Have you considered using the paths option? This will allow you to tell typescript that the module 'indico-url:plugin_vc_zoom.static' has type definitions at (your local copy of the module), which will allow TS to type check and intellisense your usage of the module's functions.
If you don't have type definitions, you can use declare module "indico-url:*"; in a declaration file to type it as any.

Duplicate #19139

@jcalz That issue is about being able to distinguish between errors when using @ts-ignore, but this issue seems to be about being able to globally hide errors (using the tsconfig).

Thanks everyone, that seems to work. I had no idea you could use wildcards in module names. I'll close the issue.

authors: BalaM314 MartinJohns jcalz pferreir


text:
Updates to type reference directive resolution and module resolution when failed

When user has supplied typeRoots resolve the typeReference as file or directory instead of just directory resolution as before.
1c2318d92e2e93c99b8ed87419470ddfd7719796 This is fix for issue Bug 2 reported in #37708
If configuration has supplied typeRoots stop looking into node_modules/@types containing file's ancestor directories to resolve type reference as secondary lookup.
40bb75c8f5273d5cd379c97cb683f08a04947b58 This is fix for issue Bug 1 reported in #37708
When resolving modules, if resolution fails, try resolving it from typeRoots if user has supplied. This helps solve the issues with module augmentation etc if when types are included through typeRoots.
a6fed14f5bb2279bac45f348f49ee984baa3512d This is fix for #39691 and #37958

Fixes #37708, #39691, #37958, #44270

@typescript-bot run dt
@typescript-bot test top100

@sheetalkamat  I'm going through all the ready-to-merge PRs, and this one was intended either for 5.0 or 5.1, so I vote to merge it now that 5.1 development has started.

I still confuse with the usage of "typeRoots" under Typescript 5.1-beta.
Here is my simple example.
My project structure:
typescript1
 ┣ @types
 ┃ ┗ mypackage
 ┃   ┗ index.d.ts
 ┣ node_modules
 ┣ src
 ┃ ┗ 5-1-main.ts
 ┣ package.json
 ┗ tsconfig.json

my package.json:
{
  "name": "typescript1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "tsc": "tsc ./src/5-1-main.ts",
    "tsct": "tsc ./src/5-1-main.ts --traceResolution",
    "tscv": "tsc -v"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {},
  "dependencies": {
    "typescript": "beta"
  }
}

my tsconfig.json:
{
  "compilerOptions": {
    "target": "es2016",
    "module": "esnext",
    "typeRoots": ["./@types"]
  },
}

my custom type defined file:
// ./@types/mypackage/index.d.ts
interface MyObject {
    name: string;
}

my source code:
// ./src/5-1-main.ts
var a: MyObject = {
    name: '12',
}

Before I run the script npm run tsc, I run tscv to ensure my typescript version is 5.1-beta.

Then I run script npm run tsc.I got  the error:
src/5-1-main.ts:1:8 - error TS2552: Cannot find name 'MyObject'. Did you mean 'Object'?

1 var a: MyObject = {
         ~~~~~~~~

  node_modules/_typescript@5.1.0-beta@typescript/lib/lib.es5.d.ts:270:13
    270 declare var Object: ObjectConstructor;
                    ~~~~~~
    'Object' is declared here.

Found 1 error in src/5-1-main.ts:1

I specified the typeRoots in tsconfig.json, but MyObject defined in file ./@types/mypackage/index.d.ts not worked.
Then I added the file @types/mypackage2/index.d.ts into the dir ./node_modules.
typescript1
 ┣ @types
 ┃ ┗ mypackage
 ┃   ┗ index.d.ts
 ┣ node_modules
 ┃ ┗ @types
 ┃      ┗ mypackage2
 ┃          ┗ index.d.ts
 ┣ src
 ┃ ┗ 5-1-main.ts
 ┣ package.json
 ┗ tsconfig.json

And I run the script npm run tsct ( tsc command with --traceResolution), typescript could compile success.According to the log, MyObject defined in file ./node_modules/@types/mypackage2/index.d.ts was involed into the compilation.
That was so weird！！
> typescript1@1.0.0 tsct /Users/sisiea/Documents/playground/typescript1
> tsc ./src/5-1-main.ts --traceResolution

======== Resolving type reference directive 'mypackage2', containing file '/Users/sisiea/Documents/playground/typescript1/__inferred type names__.ts', root directory '/Users/sisiea/Documents/playground/typescript1/node_modules/@types,/Users/sisiea/Documents/playground/node_modules/@types,/Users/sisiea/Documents/node_modules/@types,/Users/sisiea/node_modules/@types,/Users/node_modules/@types,/node_modules/@types'. ========
Resolving with primary search path '/Users/sisiea/Documents/playground/typescript1/node_modules/@types, /Users/sisiea/Documents/playground/node_modules/@types, /Users/sisiea/Documents/node_modules/@types, /Users/sisiea/node_modules/@types, /Users/node_modules/@types, /node_modules/@types'.
File '/Users/sisiea/Documents/playground/typescript1/node_modules/@types/mypackage2/package.json' does not exist.
File '/Users/sisiea/Documents/playground/typescript1/node_modules/@types/mypackage2/index.d.ts' exists - use it as a name resolution result.
Resolving real path for '/Users/sisiea/Documents/playground/typescript1/node_modules/@types/mypackage2/index.d.ts', result '/Users/sisiea/Documents/playground/typescript1/node_modules/@types/mypackage2/index.d.ts'.
======== Type reference directive 'mypackage2' was successfully resolved to '/Users/sisiea/Documents/playground/typescript1/node_modules/@types/mypackage2/index.d.ts', primary: true. ========

Yes, it's mentioned in the Announcing TypeScript 5.1 blog post.

@loick can you log a fresh issue please? Thanks!

ok

source: gharchive/pull-request

authors: Abrarhaj RyanCavanaugh andrewbranch ehoogeveen-medweb sandersn sheetalkamat sisiea


text:
Fixed a mistake in the narrowingDestructuring test

closes https://github.com/microsoft/TypeScript/issues/52410

Thanks!

authors: Andarist RyanCavanaugh


text:
Labels are incorrect in Active Learning

Incorrect labels in Active Learning

The problem seems caused by the label offset in src/providers/activeLearning/objectDetection.ts and it can be fixed by apply following patch.
Patch file
diff --git a/src/providers/activeLearning/objectDetection.ts b/src/providers/activeLearning/objectDetection.ts
index 196db45..daf7edb 100755
--- a/src/providers/activeLearning/objectDetection.ts
+++ b/src/providers/activeLearning/objectDetection.ts
@@ -222,7 +222,7 @@ export class ObjectDetection {

     private getClass(index: number, indexes: Float32Array, classes: number[]): string {
         if (this.jsonClasses && index < indexes.length && indexes[index] < classes.length) {
-            const classId = classes[indexes[index]] - 1;
+            const classId = classes[indexes[index]];
             const classObject = this.jsonClasses[classId];

             return classObject ? classObject.displayName : strings.tags.warnings.unknownTagName;

After patch

Same problem here:

I submitted a PR last week to fix this issue.  The update broke the tests which I haven't gotten around to fixing yet, but if you git clone https://github.com/csaroff/VoTT.git and then npm start, you should be good to go!

The issue was still lurking as I cloned the git just today. I was able to get the labels right by changing the src/providers/activeLearning/objectDetection.ts:225 line to
const classId = classes[indexes[index]]; // - 1;
--> So as the labels were off by one in the index, so I removed the -1 and got this working. Maybe this brakes the generally correct functioning, so maybe this is not a general fully tested fix by any means. The same 'one off label' issue was still reproducible using the Pre-trained COCO as well.

authors: Dahlasam csaroff dino-su matthieu-lapeyre

repo: microsoft/VoTT

license: MIT


text:
I can't find this package in the NuGet package Manager

Today, I use this package , I open the NuGet Package Manager and type Microsoft.Wpf.Interop.DirectX. I find I can't search this package, But the NuGet package Manager give me another package: TqkLibrary.Wpf.Interop.DirectX, Why? The Microsoft.Wpf.Interop.DirectX has been discarded?

My windows system is Windows11 and VS version is VS2022

I can find it when choose include prerelease, the I can compile success my project, but when I run, it give me an error: FileNotFoundException: 未能加载文件或程序集“Microsoft.Wpf.Interop.DirectX.dll”或它的某一个依赖项。找不到指定的模块 Why? Can you help me to solve this problem? But I use the TqkLibrary.Wpf.Interop.DirectX lib, I can success compile and run. Why?

I have install the package and compile it success, but when I run it, it give me an "FileNotFoundException: 未能加载文件或程序集“Microsoft.Wpf.Interop.DirectX.dll”或它的某一个依赖项。找不到指定的模块" Why? Would you help me to solve it?

repo: microsoft/WPFDXInterop


text:
Odd clock stretching when WSL is installed

So kind of an odd issue, is similar to the windows defender bug.
So I have my 9900K at 4.7ghz, I've known windows to be a bit finicky with windows defender specifically real time protection which messes up effective clocks. When I have real time protection enabled, my effective clocks drop 50-100mhz lower than my core clocks (4700mhz) when under load. If I turn off real time protection the effective clocks stay pegged at 4700mhz, matching the core clock. So I've edited the registry to disable real time protection permanently.
Now I have Wsl2 installed, and noticed the exact same phenomenon, I removed wsl and turned off the virtual machine check boxes inside off turn off apps and features settings, so not sure if it's wsl or the windows virtual machine setting that does it.
So, any fix for this? I'd like to still have wsl on my system, but as I'm an avid overclocker and like tinkering, I'd like my effective clocks to be matched when under load.

/questionOn Jul 31, 2024, at 9:36 PM, github-actions[bot] @.***> wrote:
Logs are required for review from WSL team
If this a feature request, please reply with '/feature'. If this is a question, reply with '/question'.
Otherwise please attach logs by following the instructions below, your issue will not be reviewed unless they are added. These logs will help us understand what is going on in your machine.
How to collect WSL logs
Download and execute collect-wsl-logs.ps1 in an administrative powershell prompt:
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/collect-wsl-logs.ps1" -OutFile collect-wsl-logs.ps1
Set-ExecutionPolicy Bypass -Scope Process -Force
.\collect-wsl-logs.ps1
The script will output the path of the log file once done.
If this is a networking issue, please use collect-networking-logs.ps1, following the instructions here
Once completed please upload the output files to this Github issue.
Click here for more info on logging
If you choose to email these logs instead of attaching to the bug, please send them to @.*** with the number of the github issue in the subject, and in the message a link to your comment in the github issue and reply with '/emailed-logs'.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

repo: microsoft/WSL


text:
Custom resolv.conf being replaced by generated file, even with comment removed.

A brief description
Custom /etc/resolv.conf overwritten, even when "# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line." is removed.

Expected results
Custom /etc/resolv.conf should not be overwritten when comment is removed.

Actual results (with terminal output if applicable)
Custom /etc/resolv.conf replaced with standard generated /etc/resolv.conf

Your Windows build number
1703 - OS Build 15063.138

If I remove /etc/resolv.conf - which was a symlink -> /run/resolvconf/resolv.conf it will not remove my custom /etc/resolv.conf.
I can't verify but is it possible that this behavior changed from 14.04 -> 16.04 so the symlink isn't being followed by WSL when checking for the comment?

Did you modify /etc/resolv.conf or  /run/resolvconf/resolv.conf?

If the /etc/resolv.conf symlink was in place it would implicitly only modify /run/resolvconf/resolv.conf - and changes would always be automatically overwritten as long as /etc/resolv.conf was a symlink.

It looks like there is an issue that is causing the resolv.conf file to be regenerated each time an instance is launched.  We are looking at ways to improve this experience.

Sorry, did not mean to close.

Here is some more background. By default, bash.exe will auto-generate /etc/resolv.conf every time you launch bash.exe. Then it will try to keep it up to date with changes from Windows, when bash is running. We somehow screwed up the logic to stop-auto generation when you remove the first line. It looks like if you remove the first line, we stop auto-update of the file while bash is running, but forgot to disable the logic to auto-generate during bash launch. We do apologize for the inconvenience and as @benhillis mentions, we are looking to improve the experience here.

The problem still persists in Insider Preview 16241.
I solved this issue by following steps

Delete /etc/resolv.conf
Make /etc/resolv.conf by vim/nano
Insert appropriate nameservers.
Done!

Logout and the again run bash on cmd

@sunilmut is currently looking at this.

Thanks @bradley101. For this release (Fall Creators Update), we will have to live with the workaround you have pointed out, here. For next release, we will relook at the better support for other VPN solutions.

followed @bradley101 workaround and back in business.

Issue is still there in current Windows release

FTR remains an issue as part of Win 10 Pro Build 17134
That said, @bradley101 's solution worked for me on my Win10 Ubuntu WSL.
Cheers.

This fella helped me out with this issue: https://grayson.sh/blogs/fixing-wsl-search-domains

@andrewr01 that link to Kent Grayson's blog worked for me.
I would say to anybody looking to employ Kent's solution that you may want to keep an original copy of the resolv.conf instead of moving it wholesale like his instructions promote. Otherwise, I appear to be good for now and will report back if anything comes up.

How has this not yet been fixed?

Can confirm. The file is still being overridden whenever bash.exe is executed. None of the proposed solutions worked for me.

The workaround provided does not survive a reboot. Come on guys, it's been 3 years.

@gustavlasko , @KevinSilvaQuintana , and @michaelklachko the workaround noted by @andrewr01 back on Feb 18, 2019 has persisted for me since I noted as much on Feb 19.

I feel like rm'ing a symlink and 'sudo cat content >> /etc/resolv.conf' should not be part of my daily workflow anymore, does anyone know if this is going to be fixed in the WSL 2 general release?

how is this still not fixed? do you guys just not care any more?

Note: Since the last time I nuked the symlink and replaced the file, it's stuck, so this may have been fixed silently in an update that happened sometime this quarter. Thanks all!

None of the solutions work for me. Not ready for prime time.

Once you edit the resolv.conf file, you can do:
sudo chattr +i /etc/resolv.conf  - which will make the file immutable and won't be overwritten next time you start wsl.

What many of you guys are likely running into, is /etc/resolv.conf is typically a symlink to a file that resides in a tmpfs mount (that will be recreated each time the instance is started).
root@BENHILL-DELL:/c/Users/benhill# readlink /etc/resolv.conf
../run/resolvconf/resolv.conf
root@BENHILL-DELL:/c/Users/benhill# mount | grep -i run
none on /run type tmpfs (rw,nosuid,noexec,noatime,mode=755)

I'd suggest deleting this symlink and replacing it with a regular file.

I followed the instructions given by /etc/resolv.conf and added to /etc/wsl.conf:
[network]
generateResolvConf = false
This does not seem to prevent /etc/resolv.conf from being auto-generated, regardless of whether or not it is a link to /var/run/resolvd/resolv.conf
I did try 'chattr +i /etc/resolv.conf' suggested by @lostbg and that caused /etc/resolv.conf to remain persistent, but that strikes me more as a "utilitarian dirty hack" rather than a solution, since I'm probably going to forget what I did, and then wonder why I can't edit resolv.conf in the future.
I totally get the behavior for new users who don't want to mess with their DNS settings, but either there needs to be a different solution, or at least the documented solution in the file should work.

None of the workarounds work for me either (my file will be overwritten on launch of bash.exe regardless of any of the suggested steps)
OS Build 19.041.329

This worked for me on WSL2 -
/etc/wsl.conf
[network]
generateResolvConf = false

Inside a wsl session -
sudo rm /etc/resolv.conf
# create your own /etc/resolv.conf
sudo vim /etc/resolv.conf

Immediately shutdown wsl, do not start another session until you execute from a windows command prompt.
wsl --shutdown

The shutdown was what I was missing.  Maybe they should update that message to be useful.

Yes, it doesn't appear to reload the wsl.conf file until wsl --shutdown, so if you start a new terminal before completely shutting down wsl it clobbers /etc/resolv.conf with a symlink to the auto-generated file.

Indeed the wsl --shutdown command from the windows command line was successfull! Thank you @j-c-m

This worked for me on WSL2 -
/etc/wsl.conf
[network]
generateResolvConf = false

Inside a wsl session -
sudo rm /etc/resolv.conf
# create your own /etc/resolv.conf
sudo vim /etc/resolv.conf

Immediately shutdown wsl, do not start another session until you execute from a windows command prompt.
wsl --shutdown

This solution works for me, thanks!

Once you edit the resolv.conf file, you can do:
sudo chattr +i /etc/resolv.conf  - which will make the file immutable and won't be overwritten next time you start wsl.

I've been searching for a solution to this for ages, this did the trick for me! Thanks

First of all @j-c-m's suggestion also worked for me.
But! I did a silly mistake, that kept me struggling for a bit longer. So my here it is, just in case.

Make sure you also uncomment the [network] header.
So that the change in wsl.conf looks indeed like this:
[network]
generateResolvConf = false

And NOT like this
# [network]
generateResolvConf = false

First of all @j-c-m's suggestion also worked for me.
But! I did a silly mistake, that kept me struggling for a bit longer. So my here it is, just in case.

Make sure you also uncomment the [network] header.
So that the change in wsl.conf looks indeed like this:
[network]
generateResolvConf = false

And NOT like this
# [network]
generateResolvConf = false

I found this solution to work very well. Is important to shutdown WSL2 in a correct way so it accepts the changed settings.
do above or here settings.  then shutdown WSL via command from cmd or powershell .
wsl.exe --terminate NAME_OF_YOUR_LINUX

and open a WSL one more time, this time the settings should be persisted as it supposed.

Behavior is slightly different than written above for me.  I've added the correct entry to wsl.conf:
[network]
generateResolvConf = false

After wsl --shutdown then wsl -d Ubuntu-20.04 There is no symlink or any other kind of /etc/resolv.conf.  I make a new one with the entries I want.  DNS resolution starts working again properly.
On subsequent launch of wsl the /etc/resolv.conf is gone.  It seems to be removed upon launch every time.
The only fix that has worked for me is chattr +i /etc/resolv.conf.  That's treating the symptom rather than the cause though :/

For me /etc/resolv.conf also resets despite having added the correct entry to wsl.conf, removing the symlink and creating my own resolv.conf, and it's not even just on restarting WSL or opening a new session - sometimes it seems to happen even when I leave the computer running overnight.

Algorithm that worked for me:

Add following to //etc/wsl.conf:

[network]
generateResolvConf = false

Remove symlink and create new resolv.conf:

sudo rm /etc/resolv.conf
sudo micro /etc/resolv.conf

Add following to resolv.conf:

nameserver 192.168.1.1
# (or whatever DNS adress you need)

Shutdown WSL from Powershell:
wsl --shutdown

Start WSL session again just like usual and check if it helps

when not generating the resolv.conf you risk to loose your network connectivty from WSL as soon as your IP changes on the host.
easiest way to mittigate that is to have in wsl.conf
[network]
generateResolvConf = true
this leads to a generated resolv.conf
and within your ~/.bashrc you add:
sudo bash -c 'echo "nameserver xxx.xxx.xxx.xxx" >> /etc/resolv.conf'
for every name server you want to have in there. Like this, every time you login, your additional network config is added to the resolv conf and all is fine, no more headache.

when not generating the resolv.conf you risk to loose your network connectivty from WSL as soon as your IP changes on the host.

Thanks for the info, this looks more proper way to solve the issue.

@liechtir I gave it a try and it doesn't work the way i expected in my case. Reasons:

it does require root password every time i log in which is not comfortable.
generated resolv.conf already have nameserver ip (172.25.16.1). I don't know what ip is it, maybe some virtual environment stuff and like that, anyway it never works.
then i echoing my nameserver as you mentioned, it leads to significant delay in name resolution, for example i use simple ping command and only after 5-6 seconds it start actually pinging. Maybe because it tries first (in my case broken) ip in a list of nameservers.

My DNS ip never changes, because it is ip of my home router, so for now, i decided to turn off autogenerate resolv.conf. If i doing something wrong anybody please correct me.

@benhillis How does this still not work consistently after 5.5 years?

@benhillis How does this still not work consistently after 5.5 years?

Since the file is regenerated when bash.exe starts, and it keeps the file updated while it runs (see https://github.com/microsoft/WSL/issues/1350#issuecomment-296282844), I'm not surprised that WSL is not stable. I mean, where the architects were, when this decision was made?

This worked for me on WSL2 -
/etc/wsl.conf
[network]
generateResolvConf = false

Inside a wsl session -
sudo rm /etc/resolv.conf
# create your own /etc/resolv.conf
sudo vim /etc/resolv.conf

Immediately shutdown wsl, do not start another session until you execute from a windows command prompt.
wsl --shutdown

Worked for me!!!

authors: Johawila KatSteinke KevinSilvaQuintana Spongman adipose andrewr01 benhillis bradley101 brandonmreese daghb glasko-dp gustavlasko j-c-m jakethedev julian7 jvosper liechtir lmayorga1980 lostbg mehrdadnd mezhgano michaelklachko mokonofua niilz seffyroff sp0ker stivo85 sunilmut tonyvitonis unix-geek


text:
Unable to install/enable Virtual Machine Platform

I'm on build 19008.  Whenever I try to install/enable Virtual Machine Platform I get a green screen (attached).  I did not install either Windows Subsystem For Linux or Virtual Machine Platform prior to this attempt, on any previous versions of Windows - this is the first time.
I am able to successfully enable Windows Subsystem for Linux and install a distro.  It is only Virtual Machine Platform that causes the green screen.  I've updated all my drivers and there are no "!" alerts in Device Manager.  I've unplugged all peripherals.  Nothing seems to work.

tmcomm.sys is not owned by Microsoft, it is the Trend Micro Internet Security driver by Trend Micro.

You're right, my bad - I didn't see the "What failed" line.  I've disabled that, and now I get a green screen that does not have the line "What Failed", but the same Stop Code: PAGE_FAULT_IN_NONPAGED_AREA.  Like I mentioned, I've updated all my drivers and I have no alerts in device manager, so I'm stumped as to what else could cause this on my end.

I've disabled Trend Micro

Disabling generally has little effect on kernel drivers.

would it make a difference if I tried booting into Safe Mode and installing it from there?

Dunno if WSL runs in safe mode. Even if it did, if WSL ran successfully, you'd learn: "there is some third-party thing installed in the kernel that is faulting". Which you already know.

Thanks so much for the feedback, I sincerely appreciate it.  I'll get rid of Trend Micro and give it a shot!

A quick follow-up: uninstalling Trend Micro fixed the issue.  I haven't tried reinstalling Trend Micro yet.

authors: benhillis smare therealkenc


text:
TrueCrypt drives don't show up in WSL

Reproducer:

Download Windows TrueCrypt 7.1a from grc.com.  (Don't use TrueCrypt 7.2; TrueCrypt has been discontinued, that version is only capable of decrypting existing drives.)
Install the application. Open the application.
Create a file-backed encrypted volume.  Stick with the default encryption settings.  Format it as FAT.
Still in the TrueCrypt application, select the volume's file, and Mount it to a drive letter.

Expected:

Drive should appear as a writeable volume in My Computer, mapped to the specified drive letter
Drive letter should show up in /mnt/ within WSL and should be mapped to the same drive as in Windows

Actual:

Drive does appear in My Computer as expected, apparently mapped to the specified drive letter
Drive does not appear in /mnt/ within WSL

I realize that TrueCrypt is a long-since-deprecated application.  And that its web presence looks a bit sketchy.  I don't currently have an actual use for it.  But I had it set up once and noticed this behavior, so I figured I would file it just so y'all are aware that this scenario is possible.

VeraCrypt is a derivative of TrueCrypt, and at this time it is still supported.

See #131.

@therealkenc This looks like a different thing: a filesystem mounted on the windows side isn't showing up in DrvFs. It could be something to do with how TrueCrypt registers volumes?

If the TrueCrypt volume NTFS or FAT?  Currently only fixed NTFS drives will show up in DriveFs.

Ooh, interesting -- NTFS has a much-worse failure mode :-)  Will file a separate bug momentarily so that it gets attention as a separate issue.
Regarding FAT -- that's good to know.  Do y'all have plans to support non-NTFS filesystems?  Linux itself does.  It works around their lack of metadata support by setting (per-mount-configurable) default permissions; the default of 777 for everything seems to be adequate for many use cases.  NTFS support on Mac and (real) Linux still isn't as robust as their FAT support so some of my external drives are FAT-formatted; I don't always remember which are which and would find it a bit confusing if some appeared in WSL and others didn't.  (Though, to be fair, I haven't actually encountered this yet.)

Edited the text of this ticket to specify a filesystem format of FAT specifically, rather than "FAT or something else reasonable".

I can confirm that a VeraCrypt volume formatted with NTFS does show up without a problem.

This is still open so I'm gonna bump it.
I'm using VeraCrypt, my mount is NTFS drive, but it still doesn't show up in /mnt
Any advices how to mount it manually maybe?

Are you in WSL2 realm?

If you want to know if I'm on new or old WSL, then I'm probably on old one, as I'm still on 1809, build 17763.615.

Edit: closing all WSL windows fixed that. Just closing one of them and trying in new window wasn't enough. I guess that's a bug?

@dzek69 thanks for sharing, solved the issue in my case.

Not working for me, i.e. this idea of mount the drive, then close all WSL windows.  I'm still not seeing anything for this VC drive under /mnt ... Incidentally this is WSL2, OS Version "10.0.19042" aka "20H2".

Had the same problem: NTFS partition didn't show up in /mnt. I have WSL 2 with Windows 10 version 2004.
What worked for me wasn't exactly closing all the WSL windows, but by running wsl --shutdown in command prompt, and opening a wsl shell again.
After going into /mnt, I saw my mounted NTFS volume!
However, my exFAT volume doesn't show up at all in WSL, under veracrypt version 1.24-Update7. Guess I'll switch it to NTFS 🙃

Veracrypt is working for me with WSL2. I would suggest mounting the drive, terminating the wsl instance wsl --terminate <instance name>, and then restarting the ubuntu terminal.


text:
WSL2 terminates the moment my laptop is unplugged from electricity

Environment
Windows build number: Microsoft Windows [Version 10.0.19041.508]
Your Distribution version: Debian 10
Whether the issue is on WSL 2 and/or WSL 1: WSL 2, Linux version 4.19.128-microsoft-standard (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Tue Jun 23 12:58:10 UTC 2020
Device: laptop Acer Aspire 3 A315-42G-R68U

Steps to reproduce

I launch WSL on my laptop  while it's plugged in
I unplug the laptop

or

I launch WSL on my laptop while it's unplugged
I plug the laptop in
I unplug the laptop (duration of being plugged in doesn't matter)

WSL logs:
https://aka.ms/AAagc4m
Expected behavior

WSL stays working normally
Actual behavior

WSL terminates with no error message 1.5 seconds after: at first the console area disappears and only light-gray window is left, then the window closes as well. The whole termination takes about 1 sec more than manual closing (e.g. Alt-F4)

Did you try with WSL1?

@Biswa96 I used to use WSL1 for a little while, but it's hard to say whether this issue doesn't happen with WSL1 or I just never tried to unplug the laptop with WSL1 running.
dmesg.log

@Biswa96 I used to use WSL1 for a little while, but it's hard to say whether this issue doesn't happen with WSL1 or I just never tried to unplug the laptop with WSL1 running. Here are the logs:
dmesg.log

By Anychance you use Battery Care? If yes then, it's the problem, probably. It stop some service and probably some service needed by WSL is killed

@Biswa96 I used to use WSL1 for a little while, but it's hard to say whether this issue doesn't happen with WSL1 or I just never tried to unplug the laptop with WSL1 running. Here are the logs:
dmesg.log

By Anychance you use Battery Care? If yes then, it's the problem, probably. It stop some service and probably some service needed by WSL is killed

I just tested with Windows' power saver mode off and everything switched to maximum performance on battery and it crashes anyway. I'm not sure if the issue is indeed in some service being shutdown, because services usually take some time to launch, but in my case I can immediately launch WSL after crash (so the needed services are probably intact or launched by WSL itself).

Are there any updates for WSL2?
Because it still reproduces with WSL2, it is not loading while working unplugged

@CeSiumUA Seems there are none, and tied specifically to some brand or updates, I try to reproduce on clean install, can't reproduce. Can you share the build ID of the windows, the laptop brand, and paste it here? It will help, I think to narrow down the problem.
NOTE: I'm not microsoft employee, just some other user

@CeSiumUA
No Need for serial, please remove the serial. I hope the dev pick this,
Hmm you already get the latest January Monthly update, strange.... I have same Build number, on different manufacture, not reproduceable... Last time, on windows 10, they suddenly fix the code, without any notice, using monthly update... I don't know whether they will done the same to windows 11

My wsl2 stops working after I set my Laptop on sleep mode. Everytime...

authors: Biswa96 CeSiumUA benyaminl kierke-gaard laralex


text:
v2/snaps/chromium   System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down

Windows Build Number
19041
WSL Version
WSL 2
Distro Version
Ubuntu 20.04
Other Software
installing Chromium-browser in Ubuntu with VS Code, Windows Terminal,
Repro Steps
$ sudo apt install chromium-browser
chromium-browser is already the newest version (1:85.0.4183.83-0ubuntu0.20.04.2).
$ snap install chromium
error: cannot communicate with server: Post http://localhost/v2/snaps/chromium: dial unix /run/snapd.socket: connect: no such file or directory
$ sudo systemctl unmask snapd.service
$ sudo systemctl enable snapd.service
$ sudo systemctl start snapd.service
System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
Expected Behavior
Should be able to open a Chromium browser from bash terminal by running chromium-browser
Actual Behavior
chromium-browser is installed, however the command outputs as below
$ chromium-browser
Command '/usr/bin/chromium-browser' requires the chromium snap to be installed.
Please install it with:

snap install chromium

Diagnostic Logs
No response

/dupe #5126

authors: newcanopies therealkenc


text:
Error code: Wsl/InstallDistro/0x8007139f on Windows Server 2022

Version
Microsoft Windows [version 10.0.20348.1311]
under Hyper-V, Nested Virtualisation activated, Intel CPU
WSL Version

[X] WSL 2
[ ] WSL 1

Kernel Version
No response
Distro Version
No response
Other Software
No response
Repro Steps
wsl --install
(reboot)
wsl --install Ubuntu
Expected Behavior
get in Ubuntu
Actual Behavior
Wsl/InstallDistro/0x8007139f
Diagnostic Logs
https://techcommunity.microsoft.com/t5/itops-talk-blog/using-wsl-2-on-windows-server-2022-to-run-linux-containers/bc-p/3688927/highlight/true#M2411

/logs

WslLogs-2022-12-02_21-53-50.zip

I am having the same issue, and have attached my log file output in case it helps.
WslLogs-2022-12-06_14-12-20.zip

Thank you @sirber. Based on the logs, it looks like the application package failed to install.
Can you share the output of  Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName.contains("buntu")} in an elevated powershell ?
I wonder if the application is installed in a bad state, or for another user.

Get-AppxPackage -AllUsers | Where-Object { $_.PackageFamilyName.contains("buntu")}

nothing shows up

Hello,
Same configuration as @sirber  and same issue
here is my logs
Please help, it's the 3rd time a make the operation and no success.
WslLogs-2022-12-07_15-03-19.zip

Thank you!! It works!
Powershell:
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -Out Microsoft.VCLibs.x64.14.00.Desktop.appx
Add-AppxPackage .\Microsoft.VCLibs.x64.14.00.Desktop.appx

This issue is not solved, at least for me. Starting with the latest Windows Server 2022 VHD from https://go.microsoft.com/fwlink/p/?linkid=2195166&clcid=0x409&culture=en-us&country=us it still shows Error code: Wsl/InstallDistro/0x8007139f.
Here's sample run:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\Administrator> wsl --version
WSL version: 1.0.0.0
Kernel version: 5.15.74.2
WSLg version: 1.0.47
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.20348.1311

PS C:\Users\Administrator> wsl --status
Default Version: 2

PS C:\Users\Administrator> wsl --install -d Ubuntu
Downloading: Ubuntu
Installing: Ubuntu
Ubuntu has been installed.
Launching Ubuntu...
The group or resource is not in the correct state to perform the requested operation.
Error code: Wsl/InstallDistro/0x8007139f

PS C:\Users\Administrator> Get-AppxPackage -name Microsoft.VCLibs.140.00

Name              : Microsoft.VCLibs.140.00
Publisher         : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture      : X64
ResourceId        :
Version           : 14.0.27810.0
PackageFullName   : Microsoft.VCLibs.140.00_14.0.27810.0_x64__8wekyb3d8bbwe
InstallLocation   : C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00_14.0.27810.0_x64__8wekyb3d8bbwe
IsFramework       : True
PackageFamilyName : Microsoft.VCLibs.140.00_8wekyb3d8bbwe
PublisherId       : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : False
NonRemovable      : False
IsPartiallyStaged : False
SignatureKind     : Store
Status            : Ok

PS C:\Users\Administrator> wsl -l -v
Windows Subsystem for Linux has no installed distributions.

Use 'wsl.exe --list --online' to list available distributions
and 'wsl.exe --install <Distro>' to install.

Distributions can also be installed by visiting the Microsoft Store:
https://aka.ms/wslstore
Error code: Wsl/WSL_E_DEFAULT_DISTRO_NOT_FOUND

PS C:\Users\Administrator> wsl --install -d Debian
Downloading: Debian GNU/Linux
Installing: Debian GNU/Linux
Debian GNU/Linux has been installed.
Launching Debian GNU/Linux...

PS C:\Users\Administrator> wsl -l -v
  NAME      STATE           VERSION
* Debian    Running         2

PS C:\Users\Administrator> wsl --list --online
The following is a list of valid distributions that can be installed.
Install using 'wsl.exe --install <Distro>'.

NAME               FRIENDLY NAME
Ubuntu             Ubuntu
Debian             Debian GNU/Linux
kali-linux         Kali Linux Rolling
SLES-12            SUSE Linux Enterprise Server v12
SLES-15            SUSE Linux Enterprise Server v15
Ubuntu-18.04       Ubuntu 18.04 LTS
Ubuntu-20.04       Ubuntu 20.04 LTS
OracleLinux_8_5    Oracle Linux 8.5
OracleLinux_7_9    Oracle Linux 7.9

PS C:\Users\Administrator> wsl --install -d Ubuntu-20.04
Downloading: Ubuntu 20.04 LTS
Installing: Ubuntu 20.04 LTS
Ubuntu 20.04 LTS has been installed.
Launching Ubuntu 20.04 LTS...
The group or resource is not in the correct state to perform the requested operation.
Error code: Wsl/InstallDistro/0x8007139f

PS C:\Users\Administrator> wsl -l -v
  NAME      STATE           VERSION
* Debian    Stopped         2

PS C:\Users\Administrator> wsl --status
Default Distribution: Debian
Default Version: 2

PS C:\Users\Administrator> wsl --version
WSL version: 1.0.0.0
Kernel version: 5.15.74.2
WSLg version: 1.0.47
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.20348.1311

PS C:\Users\Administrator>

Notice that Microsoft.VCLibs.140.00 was already present (it came with the VHD) and Debian installation worked as expected. Only Ubuntu (currently pulling 22.04) and Ubuntu-20.04 failed.

I reopened the issue. Glad to hear that Debian works out of the box!

Hello,
This issue is not solved
I installed the dependency, the installation was able to continue, Ubuntu downloaded and installed.
But once it was launched, i had an other issue :
WslRegisterDistribution failed with error: 0x800706d9
I tried the fixes mentioned in  #5331 but it didn't work. My VM won't start anymore !!!
I ended up deleting and recreating a VM for the 10th time.
Either it's WSL not working at all on a Windows Server 2022 over Azure stack VM, or it's Ubuntu.
I'll try Debian and come back
Thanks

have you tried installing the kernel update? it's a required step on Windows 10 and WSL2.

hey hey
in adition, i did those steps

wsl --set-default-version 2
Download and install the Linux kernel (https://aka.ms/wsl2kernel), for WSL 2 to use

and now it work:

@elsaco to give some context:
You seem to have Microsoft.VCLibs.140.00 installed, but the requirement is Microsoft.VCLibs.140.00.UWPDesktop, which is a different package (see the link I shared previously).
But beyond that, your message made me look into Ubuntu-20.04, and there was indeed an issue on this distro (fixed in #9279), so thank you for that.

Great work! 😄

Same issue. PS noted from @sirber fixed it.

I have the same issue with Windows 10 20H2 (OS Build 19042.2364)
I have run the script @sirber used, didn't help. Microsoft.VCLibs.140.00.UWPDesktop is installed.
Windows store is blocked (corporate computer) so I used --web-download to bypass that restriction.
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\WINDOWS\system32> Get-AppxPackage -name Microsoft.VCLibs.140.00.UWPDesktop

Name              : Microsoft.VCLibs.140.00.UWPDesktop
Publisher         : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture      : X64
ResourceId        :
Version           : 14.0.30704.0
PackageFullName   : Microsoft.VCLibs.140.00.UWPDesktop_14.0.30704.0_x64__8wekyb3d8bbwe
InstallLocation   : C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00.UWPDesktop_14.0.30704.0_x64__8wekyb3d8bbwe
IsFramework       : True
PackageFamilyName : Microsoft.VCLibs.140.00.UWPDesktop_8wekyb3d8bbwe
PublisherId       : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : False
NonRemovable      : False
IsPartiallyStaged : False
SignatureKind     : Store
Status            : Ok

PS C:\WINDOWS\system32> wsl --version
WSL version: 1.0.3.0
Kernel version: 5.15.79.1
WSLg version: 1.0.47
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.19042.2364
PS C:\WINDOWS\system32> wsl --install -d Ubuntu --web-download
Downloading: Ubuntu
Installing: Ubuntu
Ubuntu has been installed.
Launching Ubuntu...
The group or resource is not in the correct state to perform the requested operation.
Error code: Wsl/InstallDistro/0x8007139f

WslLogs-2023-01-09_16-09-48.zip

Is it possible to install the package using winget?

It seems the problem was that I was trying to install distributions using elevated admin powershell instance. Installation succeeded with normal credentials after I imported Ubuntu with wsl --import Ubuntu2004 c:\Ubuntu .\focal-server-cloudimg-amd64-wsl.rootfs.tar.gz and after that wsl --install -d Ubuntu

I am using Windows 11 (10.0.22621.1105), was trying to reinstall Ubuntu 22.04, was receiving error Wsl/InstallDistro/0x8007139f when tried to install via wsl --install, and error 0x80073d05 when tried using Microsoft Store.
What worked for me was stopping Windows Subsystem for Linux processes on Task Manager, delete directory C:\Users\<username>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_... directory and install again.
Worked both with Microsoft Store and wsl --install.
Viewed this on this post
https://medium.com/@kasiagauza/cant-install-linux-wsl-from-microsoft-store-error-0x80073d05-5639d9becbdb#:~:text=A quick solution for the,from removing a WSL directory.

I am currently experiencing the same issue. I have attached my logs
WslLogs-2023-04-21_15-11-38.zip

The same error. How to fix it?

authors: Biswa96 KRAOUFI OneBlue RuffJK app-EL benhillis cintya-takahaschi elsaco kbrannon95 proludiojon pyh-129 sirber


text:
It can connect to open software via process ID？

my application open complex，the winappdriver if surpport connect the open application by Process ID?

can you share some code and which language binding are you using

repo: microsoft/WinAppDriver